#include "CBondInfoImpl.h"

#include <qbprotocol/proto/table/common_util.h>
#include <uam/ServerTimeMgr.h>
#include <uam/UserAccountManager.h>

#include <QDateTime>

#include "../ABSBondInfo.h"
#include "../BondContainer.h"
#include "../BondDict.h"
#include "../BondOptionInfo.h"
#include "../Pinyin.h"
#include "../QBBondCrmClause.h"
#include "../QBIssuerInfo.h"
#include "../QBProviceInfo.h"
#include "../QBSwSectorInfo.h"

#define NOMINMAX

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define atoi qb::proto::MathUtil::atoi

const char* strBondLib_Expired() {
  static std::string g_strRemainPeriod = QString("已到期").toLocal8Bit().data();
  return g_strRemainPeriod.c_str();
}
/*
        CBondInfo的字段已经为内存做过高度优化
        增删CBondInfo字段注意事项:
        1.其字段可选类型有两种:
                基础类型(int,uint32_t,float,double)
                优化字符串类型:如ClassMember<char[17], PackedString<0, 17>,
   kOptimizeTypePackedString> m_sAuction_Cap;
                        表示字段m_sAuction_Cap实际上使用PackedString<0, 17>
                        如果将第三个模板参数改为kOptimizeTypeNone,那么将使用char[17]

                有几种情况:
                        PackedString:主要是针对平均长度超过15个字符的,因为超过15个字符后,std::string会额外分配内存
                                std::string中原始附带的15个字节内存就浪费了
                        DateStringMap:主要优化"20190128"这样的字符串,用一个4字节的整数即可描述,无需字符串
                        TinyStringMap:这个适合类似于枚举,即所有债券的该字段的取值只有有限少量几个值,不超过65536个
                                优化的时候,实际上存储的是ushort,当读取时,从一个表中读取
                                每个字段,对应一个表(注意,TinyStringMap有2个模板参数,相同的话共享同一个表)
                                表底层是线程安全的,数据是首次写,之后只读
                为了支持在优化和不优化之间切换,ClassMember的第三个参数为kOptimizeTypeNone表示不优化
                        第三个参数必须和第二个参数配到使用,参见示例

        2.针对使用频率低且浪费空间的字段,才推荐选用优化字符串类型
        3.CBondInfoOld\CBondInfoImpl\CBondInfoDebug都要同步更改
                CBondInfoDebug中,GetBondPtr主要用于统计每个字段的使用情况
                第一个参数usage是该字段的判定类型,如果增删字段,需要同步更改kBondUsage
        4.CBondInfoDebugPart.cpp中
                CBondInfoImpl::GetFieldInfo
                CBondInfoImpl::SyncField
                这两个函数是为了以通用的方式来获取CBondInfo的每个字段的元数据信息
                也需要同步
*/

// 开启宏BONDINFO_STAT,将会在CBondInfo的每个函数接口的入口处增加USE_FIELD(CBondInfoImpl,)宏,用于统计
// CBondInfo的每个字段的额使用计数

#include "FieldDecode.hpp"

// #define BONDINFO_STAT

#define USE_FIELD(OBJ, FIELD, WRITE)
#define USE_FIELD_ADD(OBJ, FIELD, WRITE)

#define LOGDEBUG  //
#define MAX_PATH 260

template <>
bool IsTypeDataEqual<std::string>(const std::string& d1,
                                  const std::string& d2) {
  return d1 == d2;
}

namespace {
// 优化,针对  strlen\(\w+\)\s*(<|>)\s*0
inline bool IsEmpty(const char* str) {
  // 旧代码是 strlen(str)<=0;
  return str == NULL || *str == '\0';
}
inline bool IsNumber(const char* str) {
  return !IsEmpty(str) &&
         (*str == '-' || *str == '.' || (*str >= '0' && *str <= '9'));
}

void _split(std::vector<std::string>& dst, const std::string& src,
            const std::string& seps) {
  dst.clear();

  size_t last = 0;
  int kLen = seps.length();
  size_t index = src.find(seps, 0);
  while (index != std::string::npos) {
    if (index - last > 0) {
      dst.push_back(src.substr(last, index - last));
    }

    last = index + kLen;
    index = src.find(seps, last);
  }

  if (src.length() > last) {
    dst.push_back(src.substr(last));
  }
}

void _strcat(char* dst, const char* src) {
  if (dst && src && strlen(src) > 0) {
    if (strlen(dst)) {
      strcat(dst, "+");
      strcat(dst, src);
    } else
      strcpy(dst, src);
  }
}

bool _checkleepyear(int nYear) {
  if ((nYear % 100) == 0) return false;
  if ((nYear % 4) == 0) return true;
  return false;
}

void _splitdate(int DayFrom, int DayTo, char* sDateGap, int strLen,
                bool isFirst) {  // 获取时间间隔
  int Y0 = DayFrom / 10000;
  int M0 = (DayFrom % 10000) / 100;
  int D0 = DayFrom % 100;
  int Y1 = DayTo / 10000;
  int M1 = (DayTo % 10000) / 100;
  int D1 = DayTo % 100;

  if (M0 == M1 && D0 == D1) {  // 整年
    int nYear = Y1 - Y0;
    if (nYear == 0)
#if WIN32
      _snprintf_s(sDateGap, strLen, -1, "%dD", nYear);
#else
      snprintf(sDateGap, strLen, "%dD", nYear);  // TODO strLen is safe?
#endif
    else {
      if (isFirst)
#if WIN32
        _snprintf_s(sDateGap, strLen, -1, "%d.00Y", nYear);
#else
        snprintf(sDateGap, strLen, "%d.00Y", nYear);
#endif
      else
#if WIN32
        _snprintf_s(sDateGap, strLen, -1, "%dY", nYear);
#else
        snprintf(sDateGap, strLen, "%dY", nYear);
#endif
    }
    return;
  } else {  // 非整年
    int nTemp = DayTo - DayFrom;
    if (nTemp < 10000) {  // 小于一年
      QDate from(Y0, M0, D0);
      QDate to(Y1, M1, D1);
      int dDays = from.daysTo(to);
#if WIN32
      _snprintf_s(sDateGap, strLen, _TRUNCATE, "%dD", dDays);
#else
      snprintf(sDateGap, strLen, "%dD", dDays);
#endif
    } else {  // 大于一年
      int dYears = 0;
      while (nTemp > 10000) {
        dYears++;
        DayTo -= 10000;
        nTemp = DayTo - DayFrom;
      }
      Y1 = DayTo / 10000;
      float yearDays = 365.f;
      // 判定是否跨2月29日，是则366天，否则365天
      bool leep0 = _checkleepyear(Y0);
      bool leep1 = _checkleepyear(Y1);
      do {
        int dayleep;
        if (!leep0 && !leep1) break;  // 非闰年
        if (leep0) {
          dayleep = Y0 * 10000 + 229;
        }
        if (leep1) {
          dayleep = Y1 * 10000 + 229;
        }
        if (DayFrom < dayleep && DayTo > dayleep) {
          yearDays = 366.f;
        }
      } while (0);

      QDate from(Y0, M0, D0);
      QDate to(Y1, M1, D1);
      int dDays = from.daysTo(to);

#if WIN32
      _snprintf_s(sDateGap, strLen, _TRUNCATE, "%.2fY",
                  dYears + dDays / yearDays);
#else
      snprintf(sDateGap, strLen, "%.2fY", dYears + dDays / yearDays);
#endif
    }
  }
}
}  // namespace

// 改造之前是304,现在降到264	降低40字节,减少211330*40=8.06mb
// TODO: static_assert(sizeof(CBondInfoImpl) == 280 && sizeof(CBondInfoImpl) <
// 305, "CBondInfoImpl");

static_assert(sizeof(ClassMember<std::string, PackedString<200, 47>,
                                 kOptimizeTypeNone>) == sizeof(std::string),
              "CBondInfoImpl");
//////////////////////////////////////////////////////////////////////
// class CBondInfo
void* CBondInfoImpl::operator new(size_t bytes) {
  // 注意:如果使用tcmalloc,那么就不要用AllocatorPool
  BASSERT(bytes == sizeof(CBondInfoImpl));
  // return ss::base::AllocatorPool<CBondInfoImpl>::Alloc();
  return malloc(sizeof(CBondInfoImpl));
}
void CBondInfoImpl::operator delete(void* ptr) {
  // ss::base::AllocatorPool<CBondInfoImpl>::Free((CBondInfoImpl*)ptr);
  free(ptr);
}
CBondInfoImpl::CBondInfoImpl() { Clear(); }
CBondInfoImpl::~CBondInfoImpl() {}
CBondInfoImpl& CBondInfoImpl::operator=(const CBondInfoImpl& bi) {
  // 之所以单独编写一个operator=,是为了调试
  // m_sJianpin = bi.m_sJianpin;
  // m_sQuanpin = bi.m_sQuanpin;
  m_ConversionRate = bi.m_ConversionRate;
  m_sBidLimitBottom = bi.m_sBidLimitBottom;
  m_sBidLimitTop = bi.m_sBidLimitTop;
  m_IssueRate = bi.m_IssueRate;
  m_sCouponRateCurrent = bi.m_sCouponRateCurrent;
  m_sFullName = bi.m_sFullName;
  m_sFullNameEn = bi.m_sFullNameEn;
  m_sShortNameEn = bi.m_sShortNameEn;

  m_sShortName = bi.m_sShortName;
  m_sCombBondKey = bi.m_sCombBondKey;
  m_sBondKey = bi.m_sBondKey;
  m_sCombBondID = bi.m_sCombBondID;
  m_sRemainDate = bi.m_sRemainDate;
  m_sRemainDateDisplay = bi.m_sRemainDateDisplay;
  m_sTermToMaturity = bi.m_sTermToMaturity;
  m_sIssueEndTime = bi.m_sIssueEndTime;
  m_sAuctionDateTime = bi.m_sAuctionDateTime;

  // 日期字段优化
  m_NextCoupon_Date = bi.m_NextCoupon_Date;
  m_PlannedExerciseDate = bi.m_PlannedExerciseDate;
  m_sAuctionDateEnd = bi.m_sAuctionDateEnd;
  m_sOptionDate = bi.m_sOptionDate;
  m_sAuctionDateStart = bi.m_sAuctionDateStart;
  m_sIssueEndDate = bi.m_sIssueEndDate;
  m_sPaymentDate = bi.m_sPaymentDate;
  m_nPayDate = bi.m_nPayDate;
  m_sAnnounceDate = bi.m_sAnnounceDate;
  m_sIssueStartDate = bi.m_sIssueStartDate;
  m_sInterestStartDate = bi.m_sInterestStartDate;
  m_sListDate = bi.m_sListDate;
  m_sMaturityDate = bi.m_sMaturityDate;

  // 小字符串优化
  m_sYieldCurveType = bi.m_sYieldCurveType;
  m_sJointUnderwriters = bi.m_sJointUnderwriters;
  m_sUnderwrites = bi.m_sUnderwrites;
  m_sIssuerRatingInstitutionCode = bi.m_sIssuerRatingInstitutionCode;
  m_sAuction_Unit = bi.m_sAuction_Unit;
  m_sIssueType = bi.m_sIssueType;
  m_sOutlook = bi.m_sOutlook;
  m_sListedMarket = bi.m_sListedMarket;
  m_sOptionType = bi.m_sOptionType;
  m_sAutcionType = bi.m_sAutcionType;
  m_sEntCor = bi.m_sEntCor;
  m_sInstitutionType = bi.m_sInstitutionType;
  m_sMarketType = bi.m_sMarketType;
  m_sBondSubType = bi.m_sBondSubType;
  m_sInterestBasis = bi.m_sInterestBasis;
  m_sCouponFrequency = bi.m_sCouponFrequency;
  m_sCompoundFrequency = bi.m_sCompoundFrequency;
  m_sWarrant = bi.m_sWarrant;
  m_sMainUnderwriters = bi.m_sMainUnderwriters;
  m_sIssuePeriod = bi.m_sIssuePeriod;
  m_sAuction_Step = bi.m_sAuction_Step;
  m_sFRNIndexID = bi.m_sFRNIndexID;
  m_sIssuerRating = bi.m_sIssuerRating;
  m_sBondRating = bi.m_sBondRating;
  m_sInstitutionRating = bi.m_sInstitutionRating;
  m_sRateType = bi.m_sRateType;
  m_sCouponType = bi.m_sCouponType;
  m_sMaturityTerm = bi.m_sMaturityTerm;
  m_sBondID = bi.m_sBondID;
  // m_sCSCleanPrice = bi.m_sCSCleanPrice;
  // m_sCSYield = bi.m_sCSYield;
  m_sAuction_Cap = bi.m_sAuction_Cap;
  m_sAuction_Flr = bi.m_sAuction_Flr;
  m_sFixingMADays = bi.m_sFixingMADays;
  // m_sCSModifyDuration = bi.m_sCSModifyDuration;
  m_sIssuerCode = bi.m_sIssuerCode;
  m_fPlannedIssueAmount = bi.m_fPlannedIssueAmount;
  m_fActualIssueAmount = bi.m_fActualIssueAmount;
  m_fOutstandingAmount = bi.m_fOutstandingAmount;
  m_nBondFileNum = bi.m_nBondFileNum;
  m_nAdditionInfoIndex = bi.m_nAdditionInfoIndex;
  m_nOptionInfoIndex = bi.m_nOptionInfoIndex;
  // m_nCSDate = bi.m_nCSDate;
  m_nAuctionTimeStart = bi.m_nAuctionTimeStart;
  m_nAuctionTimeEnd = bi.m_nAuctionTimeEnd;
  m_nCdcAuth = bi.m_nCdcAuth;
  m_nOutlookLevel = bi.m_nOutlookLevel;
  m_flag = bi.m_flag;
  m_sPrincipayPayType = bi.m_sPrincipayPayType;
  m_Sceniority = bi.m_Sceniority;
  m_CategoryFlag = bi.m_CategoryFlag;
  return *this;
}
bool CBondInfoImpl::operator==(const CBondInfoImpl& bi) const {
  //(\w+)\s+=\s+(\w+\.\w+);
  // if(\1 != \2)return false;
  //  之所以单独编写一个operator=,是为了调试
  bool succheck = false;
  if (0) {
    class FieldArray {
      std::vector<FieldInfo> m_fields;

     public:
      FieldArray(const CBondInfoImpl* bond) { bond->GetAllFields(m_fields); }
      bool IsEqual(const CBondInfoImpl* b1, const CBondInfoImpl* b2) {
        const int capcity = 1024;
        char buf1[capcity] = {0};
        char buf2[capcity] = {0};
        int type1 = 0, type2 = 0;
        for (int i = 0; i < (int)m_fields.size(); i++) {
          const FieldInfo& fi = m_fields[i];
          int size1 = b1->ReadField(fi.offset, buf1, capcity, type1);
          int size2 = b2->ReadField(fi.offset, buf2, capcity, type2);
          if (size1 != size2 || type1 != type2 ||
              memcmp(buf1, buf2, size1) != 0)
            return false;
        }
        return true;
      }
    };
    static FieldArray fields(this);
    succheck = fields.IsEqual(this, &bi);
  }
  bool success = false;
  do {
    // 之所以单独编写一个operator=,是为了调试
    // if (m_sJianpin != bi.m_sJianpin)break;
    // if (m_sQuanpin != bi.m_sQuanpin)break;
    if (m_ConversionRate != bi.m_ConversionRate) break;
    if (m_sBidLimitBottom != bi.m_sBidLimitBottom) break;
    if (m_sBidLimitTop != bi.m_sBidLimitTop) break;
    if (m_IssueRate != bi.m_IssueRate) break;
    if (m_sCouponRateCurrent != bi.m_sCouponRateCurrent) break;
    if (m_sFullName != bi.m_sFullName) break;
    if (m_sFullNameEn != bi.m_sFullNameEn) break;
    if (m_sShortNameEn != bi.m_sShortNameEn) break;

    if (m_sShortName != bi.m_sShortName) break;
    if (m_sCombBondKey != bi.m_sCombBondKey) break;
    if (m_sBondKey != bi.m_sBondKey) break;
    if (m_sCombBondID != bi.m_sCombBondID) break;
    if (m_sRemainDate != bi.m_sRemainDate) break;
    if (m_sRemainDateDisplay != bi.m_sRemainDateDisplay) break;
    if (m_sTermToMaturity != bi.m_sTermToMaturity) break;
    if (m_sIssueEndTime != bi.m_sIssueEndTime) break;
    if (m_sAuctionDateTime != bi.m_sAuctionDateTime) break;

    // 日期字段优化
    if (m_NextCoupon_Date != bi.m_NextCoupon_Date) break;
    if (m_PlannedExerciseDate != bi.m_PlannedExerciseDate) break;
    if (m_sAuctionDateEnd != bi.m_sAuctionDateEnd) break;
    if (m_sOptionDate != bi.m_sOptionDate) break;
    if (m_sAuctionDateStart != bi.m_sAuctionDateStart) break;
    if (m_sIssueEndDate != bi.m_sIssueEndDate) break;
    if (m_sPaymentDate != bi.m_sPaymentDate) break;
    if (m_nPayDate != bi.m_nPayDate) break;
    if (m_sAnnounceDate != bi.m_sAnnounceDate) break;
    if (m_sIssueStartDate != bi.m_sIssueStartDate) break;
    if (m_sInterestStartDate != bi.m_sInterestStartDate) break;
    if (m_sListDate != bi.m_sListDate) break;
    if (m_sMaturityDate != bi.m_sMaturityDate) break;

    // 小字符串优化
    if (m_sYieldCurveType != bi.m_sYieldCurveType) break;
    if (m_sJointUnderwriters != bi.m_sJointUnderwriters) break;
    if (m_sUnderwrites != bi.m_sUnderwrites) break;
    if (m_sIssuerRatingInstitutionCode != bi.m_sIssuerRatingInstitutionCode)
      break;
    if (m_sAuction_Unit != bi.m_sAuction_Unit) break;
    if (m_sIssueType != bi.m_sIssueType) break;
    if (m_sOutlook != bi.m_sOutlook) break;
    if (m_sListedMarket != bi.m_sListedMarket) break;
    if (m_sOptionType != bi.m_sOptionType) break;
    if (m_sAutcionType != bi.m_sAutcionType) break;
    if (m_sEntCor != bi.m_sEntCor) break;
    if (m_sInstitutionType != bi.m_sInstitutionType) break;
    if (m_sMarketType != bi.m_sMarketType) break;
    if (m_sBondSubType != bi.m_sBondSubType) break;
    if (m_sInterestBasis != bi.m_sInterestBasis) break;
    if (m_sCouponFrequency != bi.m_sCouponFrequency) break;
    if (m_sCompoundFrequency != bi.m_sCompoundFrequency) break;
    if (m_sWarrant != bi.m_sWarrant) break;
    if (m_sMainUnderwriters != bi.m_sMainUnderwriters) break;
    if (m_sIssuePeriod != bi.m_sIssuePeriod) break;
    if (m_sAuction_Step != bi.m_sAuction_Step) break;
    if (m_sFRNIndexID != bi.m_sFRNIndexID) break;
    if (m_sIssuerRating != bi.m_sIssuerRating) break;
    if (m_sBondRating != bi.m_sBondRating) break;
    if (m_sInstitutionRating != bi.m_sInstitutionRating) break;
    if (m_sRateType != bi.m_sRateType) break;
    if (m_sCouponType != bi.m_sCouponType) break;
    if (m_sMaturityTerm != bi.m_sMaturityTerm) break;
    if (m_sBondID != bi.m_sBondID) break;
    // if (m_sCSCleanPrice != bi.m_sCSCleanPrice)break;
    // if (m_sCSYield != bi.m_sCSYield)break;
    if (m_sAuction_Cap != bi.m_sAuction_Cap) break;
    if (m_sAuction_Flr != bi.m_sAuction_Flr) break;
    if (m_sFixingMADays != bi.m_sFixingMADays) break;
    // if (m_sCSModifyDuration != bi.m_sCSModifyDuration)break;
    if (m_sIssuerCode != bi.m_sIssuerCode) break;
    if (m_fPlannedIssueAmount != bi.m_fPlannedIssueAmount) break;
    if (m_fActualIssueAmount != bi.m_fActualIssueAmount) break;
    if (m_fOutstandingAmount != bi.m_fOutstandingAmount) break;
    if (m_nBondFileNum != bi.m_nBondFileNum) break;
    if (m_nAdditionInfoIndex != bi.m_nAdditionInfoIndex) break;
    if (m_nOptionInfoIndex != bi.m_nOptionInfoIndex) break;
    // if (m_nCSDate != bi.m_nCSDate)break;
    if (m_nAuctionTimeStart != bi.m_nAuctionTimeStart) break;
    if (m_nAuctionTimeEnd != bi.m_nAuctionTimeEnd) break;
    if (m_nCdcAuth != bi.m_nCdcAuth) break;
    if (m_flag != bi.m_flag) break;
    if (m_sPrincipayPayType != bi.m_sPrincipayPayType) break;
    if (m_Sceniority != bi.m_Sceniority) break;
    if (m_CategoryFlag != bi.m_CategoryFlag) break;
    success = true;
  } while (0);
  BASSERT(success == succheck);
  return success;
}
bool CBondInfoImpl::operator!=(const CBondInfoImpl& bi) const {
  return !(this->operator==(bi));
}
void CBondInfoImpl::Clear() {
  m_sBondKey.Reset();  // 债券编码  "A0000012012CORLEB01"
  m_sBondID.Reset();   // 债券代码	"1280309"

  m_sListedMarket.Reset();  // CIB/SSE/SZE 代表不同的市场 "CIB"
  m_sCombBondKey.Reset();  // 带有市场后缀的BondKey   "A0000012012CORLEB01.CIB"
  m_sCombBondID.Reset();  // 带有市场后缀的BondCode  "1280309.IB"

  // m_sJianpin.Reset();
  // //简拼					编码：------ m_sQuanpin.Reset();
  // //全拼					编码：------

  m_sMarketType.Reset();  // 市场类型				1级，2级
  m_sBondSubType.Reset();  // 债劵子类别:国债，央票等  参考BONDTYPE2LOG(uint32_t
                           // nType)函数 BGB,SGB等字符
  m_sIssuerRating.Reset();  // 发行人最新评级,主体评级： AAA AA+等
  m_sIssuerRatingInstitutionCode.Reset();  // 发行人评级机构代码
  m_sBondRating.Reset();                   // 最新债项评级： AAA AA+等
  m_sInstitutionRating
      .Reset();  // 取institution_info表的institution_rating字段，主体评级，含AAA+

  m_sListDate.Reset();  // 上市日期			    编码："20121019"
                        // YYYYMMDD(年月日)
  m_sInterestStartDate
      .Reset();             // 起息日				编码："20121010"
  m_sMaturityDate.Reset();  // 到期日				编码："20181010"
  m_sPaymentDate.Reset();   // 缴款日				编码："19860414"
  m_nPayDate = 0;
  m_sOptionDate.Reset();  // 行权日期				编码："19860414"
  m_sRateType.Reset();    // 利率类型 票面
                          // 编码："Shibor","Depo","固息","FIXED"
  m_sCouponType
      .Reset();                  // 利率方式				add by lance 2015.6.25
  m_sCouponFrequency.Reset();    // 付息频率
  m_sCompoundFrequency.Reset();  // 计息频率
  m_sInterestBasis.Reset();      // 利息基础

  m_sOptionType.Reset();         // 选择权类型			含权："NON"
                                 // 显示'否';否则显示'是'是否含权
  m_sMaturityTerm.Reset();       // 偿还期限	 "6Y"
  m_sTermToMaturity.Reset();     // 偿还期限， "X+Y"
  m_sFRNIndexID.Reset();         // 基础利率代码
  m_sFixingMADays.Reset();       // 基准利率计算周期（平均）
  m_sCouponRateCurrent.Reset();  // 中标价格,票面利率

  m_fPlannedIssueAmount = 0;  // 预期发行量		100000
  m_fActualIssueAmount = 0;   // 实际发行量		add by lance 2015.6.25
  m_fOutstandingAmount = 0;  // 债券余额（以万为单位）add by lance 2016.6.20

  m_sIssuerCode.Reset();       // 发行人代码		"A000001" 判断金融债
  m_sInstitutionType.Reset();  // 机构类型			"LGE"

  m_sYieldCurveType.Reset();  // 曲线类型 "CDC.CHI.MUB.AA-"
  // m_nCSDate = 0;
  // m_sCSYield.Reset();
  // //中证估值收益率 m_sCSCleanPrice.Reset();
  // //中证估值净价 m_sCSModifyDuration.Reset();		//中证估值久期

  m_sAuctionDateStart.Reset();  // 招标建档起始日
  m_sAuctionDateEnd.Reset();    // 招标建档截止日
  m_sAuctionDateTime.Reset();   // 招标建档时间
  m_sAnnounceDate.Reset();      // 公告日期
  m_sIssueStartDate.Reset();    // 发行起始日 "20121010"
  m_sIssueEndDate.Reset();      // 发行截止日
  m_sIssueEndTime.Reset();  // 发行截止时间	"1630"	add by lance 2015.6.25
  m_sIssuePeriod.Reset();  // 募集时间 "9月上旬"等 add by lance 2015.9.9

  m_flag.SetStickFlag(false);    // 是否置顶,			编码: true:置顶
  m_flag.SetMortgageFlag('\0');  // 可质押 编码："Y"
  m_flag.SetCrossmarketFlag(
      '\0');  // 跨市场				编码："Y","N"
  m_flag.SetMunicipalFlag(
      '\0');  // 城投					编码："Y"

  m_sWarrant.Reset();            // 担保
  m_sMainUnderwriters.Reset();   // 主承销商 "X000068"
  m_sJointUnderwriters.Reset();  // 联席承销商
  m_sUnderwrites.Reset();        // 承销商列表，逗号分隔
  m_sBidLimitBottom.Reset();     // 投标区间下限
  m_sBidLimitTop.Reset();        // 投标区间上限

  m_sAuction_Flr.Reset();   // 标位下限
  m_sAuction_Cap.Reset();   // 标位上限
  m_sAuction_Step.Reset();  // 步长
  m_sAuction_Unit.Reset();  // 标位单位

  m_sRemainDate.Reset();         // 剩余期限
  m_sRemainDateDisplay.Reset();  // 界面显示的剩余期限

  m_sFullName.Reset();     // 债券全称
  m_sShortName.Reset();    // 债券简称
  m_sFullNameEn.Reset();   // 债券英文全称
  m_sShortNameEn.Reset();  // 债券英文简称

  m_sOutlook.Reset();  // 展望
  m_sEntCor.Reset();   // 公司标识字段

  m_nBondFileNum = 0;         // 可下载文件数量
  m_nAdditionInfoIndex = -1;  // 增续发信息在vector中的index;
  m_nOptionInfoIndex = -1;

  m_IssueRate.Reset();            // 发行利率
  m_PlannedExerciseDate.Reset();  // 下一行权日
  m_NextCoupon_Date.Reset();      // 下一付息日
  m_ConversionRate.Reset();       // 质押比例

  m_flag.SetValidFlag(false);

  m_nAuctionTimeStart = 0;
  m_nAuctionTimeEnd = 0;
  m_nCdcAuth = -1;
  m_nOutlookLevel = -1;

  m_sIssueType.Reset();
  m_sAutcionType.Reset();
  m_sPrincipayPayType.Reset();
  m_Sceniority.Reset();
  m_CategoryFlag.Reset();
}

bool CBondInfoImpl::IsCodeEqualTo(const char* szBondID,
                                  const char* szListedMarket) const {
  USE_FIELD(CBondInfoImpl, m_sBondID, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sBondID, szBondID) == 0 &&
      strcmp(m_sListedMarket, szListedMarket) == 0)
    return true;

  return false;
}

bool CBondInfoImpl::IsKeyEqualTo(const char* szBondKey,
                                 const char* szListedMarket) const {
  USE_FIELD(CBondInfoImpl, m_sBondKey, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sBondKey, szBondKey) == 0 &&
      strcmp(m_sListedMarket, szListedMarket) == 0)
    return true;

  return false;
}

bool CBondInfoImpl::IsEqualTo(const char* szBondID,
                              const char* szListedMarket) const {
  return IsCodeEqualTo(szBondID, szListedMarket);
}

void CBondInfoImpl::SetBondKey(const char* szKey) {
  USE_FIELD(CBondInfoImpl, m_flag, true);
  USE_FIELD_ADD(CBondInfoImpl, m_sBondKey, true);
  m_sBondKey = szKey;
  SetValidity(!IsEmpty(m_sBondKey) ? true : false);
}

void CBondInfoImpl::SetBondCode(const char* szCode) {
  USE_FIELD(CBondInfoImpl, m_sBondID, true);
  m_sBondID = szCode;
}

void CBondInfoImpl::SetCombBondKey(const char* szKey) {
  USE_FIELD(CBondInfoImpl, m_sCombBondKey, true);
  m_sCombBondKey = szKey;
}

void CBondInfoImpl::SetCombBondCode(const char* szCode) {
  USE_FIELD(CBondInfoImpl, m_sCombBondID, true);
  m_sCombBondID = szCode;
}

void CBondInfoImpl::SetMaturityTerm(const char* szMaturityTerm) {
  USE_FIELD(CBondInfoImpl, m_sMaturityTerm, true);
  m_sMaturityTerm = szMaturityTerm;
}
void CBondInfoImpl::SetPlannedIssueAmount(double fPlannedIssueAmount) {
  USE_FIELD(CBondInfoImpl, m_fPlannedIssueAmount, true);
  m_fPlannedIssueAmount = fPlannedIssueAmount;
}
void CBondInfoImpl::SetActualIssueAmount(double fActualIssueAmount) {
  USE_FIELD(CBondInfoImpl, m_fActualIssueAmount, true);
  m_fActualIssueAmount = fActualIssueAmount;
}
void CBondInfoImpl::SetOutstandingAmount(double fOutstandingAmount) {
  USE_FIELD(CBondInfoImpl, m_fOutstandingAmount, true);
  m_fOutstandingAmount = fOutstandingAmount;
}
void CBondInfoImpl::SetPaymentDate(const char* szPaymentDate) {
  USE_FIELD(CBondInfoImpl, m_sPaymentDate, true);
  m_sPaymentDate = szPaymentDate;
}
void CBondInfoImpl::SetPayDate(int nDate) {  //
  USE_FIELD(CBondInfoImpl, m_nPayDate, true);
  m_nPayDate = nDate;
}
void CBondInfoImpl::SetIssuerCode(const char* szIssuerCode) {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, true);
  m_sIssuerCode = szIssuerCode;
}
void CBondInfoImpl::SetAssetStatus(const char* sAssetStatus) {
  USE_FIELD(CBondInfoImpl, m_sAssetStatus, true);
  m_sAssetStatus = sAssetStatus;
}
void CBondInfoImpl::SetPrincipalPayType(const char* szPrincipalPayType) {
  USE_FIELD(CBondInfoImpl, m_sPrincipayPayType, true);
  m_sPrincipayPayType = szPrincipalPayType;
}
void CBondInfoImpl::SetCouponRateCurrent(const char* szCouponRateCurrent) {
  USE_FIELD(CBondInfoImpl, m_sCouponRateCurrent, true);
  m_sCouponRateCurrent = szCouponRateCurrent;
}
void CBondInfoImpl::SetWarranter(const char* szWarranter) {
  USE_FIELD(CBondInfoImpl, m_sWarranter, true);
  m_sWarranter = szWarranter;
}
void CBondInfoImpl::SetBondTag(const char* szBondTag) {
  USE_FIELD(CBondInfoImpl, m_sBondTag, true);
  m_sBondTag = szBondTag;
}
void CBondInfoImpl::SetAutcionType(const char* szAutcionType) {
  USE_FIELD(CBondInfoImpl, m_sAutcionType, true);
  m_sAutcionType = szAutcionType;
}
void CBondInfoImpl::SetAuctionDateStart(const char* szAuctionDateStart) {
  USE_FIELD(CBondInfoImpl, m_sAuctionDateStart, true);
  m_sAuctionDateStart = szAuctionDateStart;
}
void CBondInfoImpl::SetAuctionDateEnd(const char* szAuctionDateEnd) {
  USE_FIELD(CBondInfoImpl, m_sAuctionDateEnd, true);
  m_sAuctionDateEnd = szAuctionDateEnd;
}
void CBondInfoImpl::SetAuctionDateTime(const char* szAuctionDateTime) {
  USE_FIELD(CBondInfoImpl, m_sAuctionDateTime, true);
  m_sAuctionDateTime = szAuctionDateTime;
}
void CBondInfoImpl::SetAnnounceDate(const char* szAnnounceDate) {
  USE_FIELD(CBondInfoImpl, m_sAnnounceDate, true);
  m_sAnnounceDate = szAnnounceDate;
}
void CBondInfoImpl::SetIssueStartDate(const char* szIssueStartDate) {
  USE_FIELD(CBondInfoImpl, m_sIssueStartDate, true);
  m_sIssueStartDate = szIssueStartDate;
}
void CBondInfoImpl::SetIssueEndDate(const char* szIssueEndDate) {
  USE_FIELD(CBondInfoImpl, m_sIssueEndDate, true);
  m_sIssueEndDate = szIssueEndDate;
}
void CBondInfoImpl::SetIssueEndTime(const char* szIssueEndTime) {
  USE_FIELD(CBondInfoImpl, m_sIssueEndTime, true);
  m_sIssueEndTime = szIssueEndTime;
}
void CBondInfoImpl::SetIssuePeriod(const char* szIssuePeriod) {
  USE_FIELD(CBondInfoImpl, m_sIssuePeriod, true);
  m_sIssuePeriod = szIssuePeriod;
}
void CBondInfoImpl::SetAuctionTimeStart(int nAuctionTimeStart) {
  USE_FIELD(CBondInfoImpl, m_nAuctionTimeStart, true);
  m_nAuctionTimeStart = nAuctionTimeStart;
}
void CBondInfoImpl::SetAuctionTimeEnd(int nAuctionTimeEnd) {
  USE_FIELD(CBondInfoImpl, m_nAuctionTimeEnd, true);
  m_nAuctionTimeEnd = nAuctionTimeEnd;
}
void CBondInfoImpl::SetOptionType(const char* szOptionType) {
  USE_FIELD(CBondInfoImpl, m_sOptionType, true);
  m_sOptionType = szOptionType;
}
void CBondInfoImpl::SetTermToMaturity(const char* szTermToMaturity) {
  USE_FIELD(CBondInfoImpl, m_sTermToMaturity, true);
  m_sTermToMaturity = szTermToMaturity;
}

void CBondInfoImpl::SetBondName(const char* szName) {
  USE_FIELD(CBondInfoImpl, m_sFullName, true);
  if (NULL == szName) return;
  m_sFullName = szName;
}

void CBondInfoImpl::SetBondNameEn(const char* szNameEn) {
  USE_FIELD(CBondInfoImpl, m_sFullNameEn, true);
  if (NULL == szNameEn) return;

  m_sFullNameEn = szNameEn;
}

const char* CBondInfoImpl::GetBondShortName() const {
  USE_FIELD(CBondInfoImpl, m_sShortName, false);
  return m_sShortName;
}

std::string CBondInfoImpl::GetBondNameEn() const {
  USE_FIELD(CBondInfoImpl, m_sFullNameEn, false);
  const char* str = m_sFullNameEn;
  return str;
}

std::string CBondInfoImpl::GetBondShortNameEn() const {
  USE_FIELD(CBondInfoImpl, m_sShortNameEn, false);
  const char* str = m_sShortNameEn;
  return str;
}

void CBondInfoImpl::SetBondShortName(const char* szShortName) {
  USE_FIELD(CBondInfoImpl, m_sShortName, true);
  // USE_FIELD_ADD(CBondInfoImpl, m_sJianpin, true);
  // USE_FIELD_ADD(CBondInfoImpl, m_sQuanpin, true);

  if (NULL == szShortName) return;
  m_sShortName = szShortName;

  // 推迟计算,直到需要时才计算;
  // m_sJianpin = "";
  // m_sQuanpin = "";
}

void CBondInfoImpl::SetBondShortNameEn(const char* szShortNameEn) {
  USE_FIELD(CBondInfoImpl, m_sShortNameEn, true);
  if (NULL == szShortNameEn) return;
  m_sShortNameEn = szShortNameEn;
}

void CBondInfoImpl::SetFRNIndexID(const char* szIndexID) {
  USE_FIELD(CBondInfoImpl, m_sFRNIndexID, true);
  m_sFRNIndexID = szIndexID;
}
void CBondInfoImpl::SetFixingMADays(const char* szFixingMADays) {
  USE_FIELD(CBondInfoImpl, m_sFixingMADays, true);
  m_sFixingMADays = szFixingMADays;
}
void CBondInfoImpl::SetMaturityDate(const char* szDate) {
  USE_FIELD(CBondInfoImpl, m_sMaturityDate, true);
  m_sMaturityDate = szDate;
}
void CBondInfoImpl::SetBondRating(const char* szCurrent)  // 债项评级
{
  USE_FIELD(CBondInfoImpl, m_sBondRating, true);
  m_sBondRating = szCurrent;
}

void CBondInfoImpl::SetIssuerRating(const char* szIssuerRating)  // 主体评级
{
  USE_FIELD(CBondInfoImpl, m_sIssuerRating, true);
  m_sIssuerRating = szIssuerRating;
}

void CBondInfoImpl::SetCBRRating(const char* szCBRRating) {
  USE_FIELD(CBondInfoImpl, m_sCBRRating, true);
  m_sCBRRating = szCBRRating;
}

void CBondInfoImpl::SetChinaDCState(const char* szChinaDCState) {
  USE_FIELD(CBondInfoImpl, m_sChinaDCState, true);
  m_sChinaDCState = szChinaDCState;
}

void CBondInfoImpl::SetCDCRating(const char* szCDCRating) {
  USE_FIELD(CBondInfoImpl, m_sCDCRating, true);
  m_sCDCRating = szCDCRating;
}

void CBondInfoImpl::SetCSIRating(const char* szCSIRating) {
  USE_FIELD(CBondInfoImpl, m_sCSIRating, true);
  m_sCSIRating = szCSIRating;
}

void CBondInfoImpl::SetIssuerRatingInstitutionCode(
    const char* sIssuerRatingInstitutionCode) {
  USE_FIELD(CBondInfoImpl, m_sIssuerRatingInstitutionCode, true);
  m_sIssuerRatingInstitutionCode = sIssuerRatingInstitutionCode;
}

void CBondInfoImpl::SetInstitutionRating(
    const char* sInstitutionRating) {  // 主体评价 AAA+
  USE_FIELD(CBondInfoImpl, m_sInstitutionRating, true);
  m_sInstitutionRating = sInstitutionRating;
}

void CBondInfoImpl::SetMarketType(const char* szMarketType)  // 市场类型
{
  USE_FIELD(CBondInfoImpl, m_sMarketType, true);
  m_sMarketType = szMarketType;
}

void CBondInfoImpl::SetMortgage(char sMortgage)  // 可质押
{
  USE_FIELD(CBondInfoImpl, m_flag, true);
  m_flag.SetMortgageFlag(sMortgage);
}

void CBondInfoImpl::SetCrossmarket(char sCrossmarket)  // 跨市场
{
  USE_FIELD(CBondInfoImpl, m_flag, true);
  m_flag.SetCrossmarketFlag(sCrossmarket);
}

void CBondInfoImpl::SetInterestStartDate(const char* szStartdate)  // 起息日
{
  USE_FIELD(CBondInfoImpl, m_sInterestStartDate, true);
  m_sInterestStartDate = szStartdate;
}

void CBondInfoImpl::SetYieldCurveType(const char* szCurveType) {
  USE_FIELD(CBondInfoImpl, m_sYieldCurveType, true);
  if (NULL == szCurveType) return;
  m_sYieldCurveType = szCurveType;
}

// void	CBondInfoImpl::SetCSDate(uint32_t nCSDate)
//{
//	USE_FIELD(CBondInfoImpl, m_nCSDate, true);
//	m_nCSDate = nCSDate;
// }
//
// void	CBondInfoImpl::SetCSYield( const char *szYield )//m_sCSYield
//{
//	USE_FIELD(CBondInfoImpl,m_sCSYield, true);
//	m_sCSYield = szYield;
// }
//
// void	CBondInfoImpl::SetCSCleanPrice( const char *szPrice )
// //m_sCSCleanPrice
//{
//	USE_FIELD(CBondInfoImpl,m_sCSCleanPrice, true);
//	m_sCSCleanPrice = szPrice;
// }
//
// void	CBondInfoImpl::SetCSModifyDuration( const char *szDuration )
// //m_sCSModifyDuration
//{
//	USE_FIELD(CBondInfoImpl,m_sCSModifyDuration, true);
//	m_sCSModifyDuration = szDuration;
// }

void CBondInfoImpl::SetOptionDate(const char* szOptionDate) {
  USE_FIELD(CBondInfoImpl, m_sOptionDate, true);
  m_sOptionDate = szOptionDate;
}

void CBondInfoImpl::SetMunicipal(char sMunicipal) {
  USE_FIELD(CBondInfoImpl, m_flag, true);
  m_flag.SetMunicipalFlag(sMunicipal);
}

void CBondInfoImpl::SetCdcAuth(int nCdcAuth) {
  USE_FIELD(CBondInfoImpl, m_nCdcAuth, true);
  m_nCdcAuth = nCdcAuth;
}

void CBondInfoImpl::SetExpireInHoliday(bool bHoliday) {
  USE_FIELD(CBondInfoImpl, m_flag, true);
  m_flag.SetExpireInHoliday(bHoliday);
}

void CBondInfoImpl::SetCurrency(const char* sCurrency) {
  USE_FIELD(CBondInfoImpl, m_sCurrency, true);
  m_sCurrency = sCurrency;
}

void CBondInfoImpl::SetSceniority(const char* szSceniority) {
  USE_FIELD(CBondInfoImpl, m_Sceniority, true);
  m_Sceniority = szSceniority;
}

void CBondInfoImpl::SetCategoryFlag(const char* szCategoryFlag) {
  USE_FIELD(CBondInfoImpl, m_CategoryFlag, true);
  m_CategoryFlag = szCategoryFlag;
}

char sTermToMaturityImpl[32] = {0};
const char* CBondInfoImpl::GetTermToMaturity() const {
  USE_FIELD(CBondInfoImpl, m_sTermToMaturity, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityTerm, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sOptionType, false);
  const char* pTermToMaturity = m_sTermToMaturity;
  if (!IsEmpty(pTermToMaturity)) {
    const char* pDest = strchr(pTermToMaturity, '+');
    if (pDest) {
      if (pDest - pTermToMaturity < 30) {
        memset(sTermToMaturityImpl, 0, sizeof(sTermToMaturityImpl));
        memcpy(sTermToMaturityImpl, pTermToMaturity, pDest - pTermToMaturity);
        strcat(sTermToMaturityImpl, "Y");
        pDest++;
        if (!IsEmpty(pDest) &&
            strlen(pDest) + 2 + strlen(sTermToMaturityImpl) < 32) {
          strcat(sTermToMaturityImpl, "+");
          strcat(sTermToMaturityImpl, pDest);
          strcat(sTermToMaturityImpl, "Y");
        }
        return sTermToMaturityImpl;
      }
    } else {
      return m_sMaturityTerm;
    }
  }
  // add by shangyi.xin 2016-01-12 可续期债券期限+N
  else if ((!IsEmpty(m_sMaturityTerm)) && strcmp(m_sOptionType, "ETS") == 0) {
    memset(sTermToMaturityImpl, 0, sizeof(sTermToMaturityImpl));
    FIELDCOPY(sTermToMaturityImpl, m_sMaturityTerm);
    strcat(sTermToMaturityImpl, "+N");
    return sTermToMaturityImpl;
  }
  return m_sMaturityTerm;
}

const char* CBondInfoImpl::GetTermToMaturity2D() const {
  USE_FIELD(CBondInfoImpl, m_sTermToMaturity, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityTerm, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sOptionType, false);
  const char* pTermToMaturity = m_sTermToMaturity;
  if (!IsEmpty(pTermToMaturity)) {
    const char* pDest = strchr(pTermToMaturity, '+');
    if (pDest) {
      return GetTermToMaturity();  // 含权债显示不变
    } else {
      return m_sMaturityTerm;
    }
  }
  // add by shangyi.xin 2016-01-12 可续期债券期限+N
  else if ((!IsEmpty(m_sMaturityTerm)) && strcmp(m_sOptionType, "ETS") == 0) {
    return GetTermToMaturity();  // 永续债显示不变
  } else if (IsEmpty(m_sMaturityTerm))
    return m_sMaturityTerm;

  memset(sTermToMaturityImpl, 0, sizeof(sTermToMaturityImpl));
  FIELDCOPY(sTermToMaturityImpl, m_sMaturityTerm);
  int len = strlen(sTermToMaturityImpl);
  char cUnit = sTermToMaturityImpl[len - 1];
  if (cUnit != 'M' && cUnit != 'm') {
    return m_sMaturityTerm;
  }

  char s0[16];
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityDate, false);
  const char* sEnd = m_sMaturityDate;
  const char* pDest = strchr(sEnd, '-');
  int nY, nM, nD;
  if (pDest)  // yyyy-mm-dd
  {
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sEnd);
    int n = pDest - sEnd;
    s0[n] = '\0';
    nY = atoi(s0);

    pDest++;
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, pDest);
    pDest = strchr(s0, '-');
    n = pDest - s0;
    s0[n] = '\0';
    nM = atoi(s0);

    pDest++;
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, pDest);
    nD = atoi(s0);

  } else  // yyyymmdd
  {
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sEnd);
    s0[4] = '\0';
    nY = atoi(s0);

    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sEnd + 4);
    s0[2] = '\0';
    nM = atoi(s0);

    pDest++;
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sEnd + 6);
    nD = atoi(s0);
  }

  struct tm tmEnd;
  tmEnd.tm_year = nY - 1900;
  tmEnd.tm_mon = nM - 1;
  tmEnd.tm_mday = nD;
  tmEnd.tm_hour = 8;
  tmEnd.tm_min = 0;
  tmEnd.tm_sec = 0;
  time_t tEnd = mktime(&tmEnd);

  USE_FIELD_ADD(CBondInfoImpl, m_sInterestStartDate, false);
  const char* sBegin = m_sInterestStartDate;
  pDest = strchr(sBegin, '-');
  if (pDest)  // yyyy-mm-dd
  {
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sBegin);
    int n = pDest - sBegin;
    s0[n] = '\0';
    nY = atoi(s0);

    pDest++;
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, pDest);
    pDest = strchr(s0, '-');
    n = pDest - s0;
    s0[n] = '\0';
    nM = atoi(s0);

    pDest++;
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, pDest);
    nD = atoi(s0);

  } else  // yyyymmdd
  {
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sBegin);
    s0[4] = '\0';
    nY = atoi(s0);

    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sBegin + 4);
    s0[2] = '\0';
    nM = atoi(s0);

    pDest++;
    memset(s0, 0, sizeof(s0));
    FIELDCOPY(s0, sBegin + 6);
    nD = atoi(s0);
  }

  struct tm tmBegin;
  tmBegin.tm_year = nY - 1900;
  tmBegin.tm_mon = nM - 1;
  tmBegin.tm_mday = nD;
  tmBegin.tm_hour = 8;
  tmBegin.tm_min = 0;
  tmBegin.tm_sec = 0;
  time_t tBegin = mktime(&tmBegin);

  long delta = tEnd - tBegin;
  nD = delta / 60 / 60 / 24;

  memset(sTermToMaturityImpl, 0, sizeof(sTermToMaturityImpl));
  FMTBUF(sTermToMaturityImpl, "%dD", nD);
  return sTermToMaturityImpl;
}

const char* CBondInfoImpl::GetFRNIndexID() const {
  USE_FIELD(CBondInfoImpl, m_sFRNIndexID, false);
  return m_sFRNIndexID;
}

const char* CBondInfoImpl::GetFixingMADays() const {
  USE_FIELD(CBondInfoImpl, m_sFixingMADays, false);
  return m_sFixingMADays;
}

const char* CBondInfoImpl::GetCouponRateCurrent() const {
  USE_FIELD(CBondInfoImpl, m_sCouponRateCurrent, false);
  return m_sCouponRateCurrent;
}
const char* CBondInfoImpl::GetWarranter() const {
  USE_FIELD(CBondInfoImpl, m_sWarranter, false);
  return m_sWarranter;
}

const char* CBondInfoImpl::GetBondTag() const {
  USE_FIELD(CBondInfoImpl, m_sBondTag, false);
  return m_sBondTag;
}

double CBondInfoImpl::GetPlannedIssueAmount() const {
  USE_FIELD(CBondInfoImpl, m_fPlannedIssueAmount, false);
  return m_fPlannedIssueAmount;
}

double CBondInfoImpl::GetActualIssueAmount() const {
  USE_FIELD(CBondInfoImpl, m_fActualIssueAmount, false);
  return m_fActualIssueAmount;
}

double CBondInfoImpl::GetOutstandingAmount() const {
  USE_FIELD(CBondInfoImpl, m_fOutstandingAmount, false);
  return m_fOutstandingAmount;
}

const char* CBondInfoImpl::GetIssuerCode() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  return m_sIssuerCode;
}

const char* CBondInfoImpl::GetInstitutionType() const {
  USE_FIELD(CBondInfoImpl, m_sInstitutionType, false);
  return m_sInstitutionType;
}

const char* CBondInfoImpl::GetYieldCurveType() const {
  USE_FIELD(CBondInfoImpl, m_sYieldCurveType, false);
  return m_sYieldCurveType;
}

// uint32_t CBondInfoImpl::GetCSDate()const
//{
//	USE_FIELD(CBondInfoImpl, m_nCSDate, false);
//	return m_nCSDate;
// }
//
// const char * CBondInfoImpl::GetCSYield() const
//{
//	USE_FIELD(CBondInfoImpl,m_sCSYield, false);
//	return m_sCSYield;
// }
//
// const char * CBondInfoImpl::GetCSCleanPrice() const
//{
//	USE_FIELD(CBondInfoImpl,m_sCSCleanPrice, false);
//	return m_sCSCleanPrice;
// }
//
// const char * CBondInfoImpl::GetCSModifyDuration() const
//{
//	USE_FIELD(CBondInfoImpl,m_sCSModifyDuration, false);
//	return m_sCSModifyDuration;
// }

const char* CBondInfoImpl::GetAutcionType() const {
  USE_FIELD(CBondInfoImpl, m_sAutcionType, false);
  return m_sAutcionType;
}

const char* CBondInfoImpl::GetAuctionDateStart() const {
  USE_FIELD(CBondInfoImpl, m_sAuctionDateStart, false);
  return m_sAuctionDateStart;
}

const char* CBondInfoImpl::GetAuctionDateEnd() const {
  USE_FIELD(CBondInfoImpl, m_sAuctionDateEnd, false);
  return m_sAuctionDateEnd;
}

const char* CBondInfoImpl::GetAuctionDateTime() const {
  USE_FIELD(CBondInfoImpl, m_sAuctionDateTime, false);
  return m_sAuctionDateTime;
}

const char* CBondInfoImpl::GetAnnounceDate() const {
  USE_FIELD(CBondInfoImpl, m_sAnnounceDate, false);
  return m_sAnnounceDate;
}

void CBondInfoImpl::SetInstitutionType(const char* szInsType) {
  USE_FIELD(CBondInfoImpl, m_sInstitutionType, true);
  m_sInstitutionType = szInsType;
}

void CBondInfoImpl::SetListDate(const char* szListDate) {
  USE_FIELD(CBondInfoImpl, m_sListDate, true);
  m_sListDate = szListDate;
}

void CBondInfoImpl::SetListedMarket(const char* szListedMarket) {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, true);
  m_sListedMarket = szListedMarket;
}

void CBondInfoImpl::SetRateType(const char* szRateType) {
  USE_FIELD(CBondInfoImpl, m_sRateType, true);
  m_sRateType = szRateType;
}

void CBondInfoImpl::SetCouponType(const char* szCouponType) {
  USE_FIELD(CBondInfoImpl, m_sCouponType, true);
  m_sCouponType = szCouponType;
}

void CBondInfoImpl::SetCouponFrequency(const char* szCouponFrequency) {
  USE_FIELD(CBondInfoImpl, m_sCouponFrequency, true);
  m_sCouponFrequency = szCouponFrequency;
}

void CBondInfoImpl::SetCompoundFrequency(const char* szCompoundFrequency) {
  USE_FIELD(CBondInfoImpl, m_sCompoundFrequency, true);
  m_sCompoundFrequency = szCompoundFrequency;
}

void CBondInfoImpl::SetInterestBasis(const char* szInterestBasis) {
  USE_FIELD(CBondInfoImpl, m_sInterestBasis, true);
  m_sInterestBasis = szInterestBasis;
}

long CBondInfoImpl::GetRemainedDays(time_t tNow) const {
  long nDays = 0;
  bool bench_log = false;  // BOOLTEST(kProfileBenchLog);

  USE_FIELD(CBondInfoImpl, m_sCombBondKey, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityDate, false);

  int Today = 0;
  if (tNow > 0) {
    struct tm* tmNow = localtime(&tNow);
    Today = (tmNow->tm_year + 1900) * 10000 + (tmNow->tm_mon + 1) * 100 +
            tmNow->tm_mday;
  }
  {  // 如果不到起息日，从起息日开始计算
    int startDate = atoi(GetInterestStartDate());
    if (startDate <= 0) {
      if (bench_log)
        LOGDEBUG(
            "GetRemainedDays iregular bond = <%s, %s, InterestStartDate is "
            "Null or Zero>",
            GetCombBondCode(), GetBondShortName());
    }
    Today = qMax(Today, startDate);
  }

  do {
    USE_FIELD_ADD(CBondInfoImpl, m_sMarketType, false);

    int nMarketType = atoi(m_sMarketType);
    if (nMarketType != 1 && nMarketType != 2) break;  // 无效债券。剩余期限为空

    if (1 /*checkOutstandingAmount*/) {
      USE_FIELD_ADD(CBondInfoImpl, m_fOutstandingAmount, false);
      USE_FIELD_ADD(CBondInfoImpl, m_fActualIssueAmount, false);
      if (m_fOutstandingAmount < 0.00001 &&
          m_fActualIssueAmount > 0.00001) {  // 未偿还金额=0时，处理方法
        if (nMarketType == 2 &&
            !IsAddIssueBond()) {  // 二级债券，并且非增续发券
          break;
        }
      }
    }

    int maturityDate = atoi(m_sMaturityDate);
    if (maturityDate <= 0) break;     // 到期日为空，剩余期限为空
    if (Today > maturityDate) break;  //

    std::set<int> setOption;
    do {
      int optionIndex = GetOptionInfoIndex();
      if (optionIndex < 0) break;
      const CBondOptionInfo* pOpi =
          CBondContainer::instance().GetBondOptionInfo(optionIndex);
      if (!pOpi) break;
      int ret = strcmp(pOpi->GetCombBondKey(), m_sCombBondKey);
      BASSERT(ret == 0);
      if (ret != 0) break;

      const char* callstr = pOpi->GetCallStr();
      const char* putstr = pOpi->GetPutStr();

      std::vector<std::string> vctOption;
      _split(vctOption, callstr, "|");
      if (bench_log && (vctOption.size() % 2) > 0) {
        log_debug(
            "CalcRemainPeriodNew iregular bond = <%s, %s, callstr = \"%s\">",
            GetCombBondCode(), GetBondShortName(), callstr);
      }
      if (vctOption.size() > 0) {
        for (int i = 0; i < (int)vctOption.size(); i += 2) {
          setOption.insert(atoi(vctOption[i].c_str()));
        }
      }
      vctOption.clear();
      _split(vctOption, putstr, "|");
      if (bench_log && (vctOption.size() % 2) > 0) {
        log_debug(
            "CalcRemainPeriodNew iregular bond = <%s, %s, putstr = \"%s\">",
            GetCombBondCode(), GetBondShortName(), putstr);
      }
      if (vctOption.size() > 0) {
        for (int i = 0; i < (int)vctOption.size(); i += 2) {
          setOption.insert(atoi(vctOption[i].c_str()));
        }
      }
      vctOption.clear();
    } while (0);

    // 到期日
    setOption.insert(maturityDate);

    int nNextDay = 0;
    for (std::set<int>::iterator it = setOption.begin(); it != setOption.end();
         it++) {
      int optDate = *it;
      if (Today >= optDate) continue;
      nNextDay = optDate;
      break;
    }
    setOption.clear();

    if (nNextDay <= 0) break;
    struct tm tm0;
    tm0.tm_year = Today / 10000 - 1900;
    tm0.tm_mon = (Today % 10000) / 100 - 1;
    tm0.tm_mday = Today % 100;
    tm0.tm_hour = tm0.tm_min = tm0.tm_sec = 0;

    struct tm tm1;
    tm1.tm_year = nNextDay / 10000 - 1900;
    tm1.tm_mon = (nNextDay % 10000) / 100 - 1;
    tm1.tm_mday = nNextDay % 100;
    tm1.tm_hour = tm1.tm_min = tm1.tm_sec = 0;

    time_t t0 = mktime(&tm0);
    time_t t1 = mktime(&tm1);
    nDays = (t1 - t0) / 86400;

  } while (0);
  return nDays;
}

void CBondInfoImpl::SetMainUnderwriters(const char* sUnderwriters) {
  USE_FIELD(CBondInfoImpl, m_sMainUnderwriters, true);
  m_sMainUnderwriters = sUnderwriters;
}

void CBondInfoImpl::SetJointUnderwriters(const char* sUnderwriters) {
  USE_FIELD(CBondInfoImpl, m_sJointUnderwriters, true);
  if (NULL == sUnderwriters) return;
  m_sJointUnderwriters = sUnderwriters;
}

void CBondInfoImpl::SetUnderwrites(const char* sUnderwrites) {
  USE_FIELD(CBondInfoImpl, m_sUnderwrites, true);
  if (NULL == sUnderwrites) return;
  m_sUnderwrites = sUnderwrites;
}

void CBondInfoImpl::SetBidLimitBottom(const char* sBid) {
  USE_FIELD(CBondInfoImpl, m_sBidLimitBottom, true);
  m_sBidLimitBottom = sBid;
}

void CBondInfoImpl::SetBidLimitTop(const char* sBid) {
  USE_FIELD(CBondInfoImpl, m_sBidLimitTop, true);
  m_sBidLimitTop = sBid;
}

void CBondInfoImpl::SetAuctionFlr(const char* sAuction) {
  USE_FIELD(CBondInfoImpl, m_sAuction_Flr, true);
  m_sAuction_Flr = sAuction;
}

void CBondInfoImpl::SetAuctionCap(const char* sAuction) {
  USE_FIELD(CBondInfoImpl, m_sAuction_Cap, true);
  m_sAuction_Cap = sAuction;
}

void CBondInfoImpl::SetAuctionStep(const char* sStep) {
  USE_FIELD(CBondInfoImpl, m_sAuction_Step, true);
  m_sAuction_Step = sStep;
}

void CBondInfoImpl::SetAuctionUnit(const char* sUnit) {
  USE_FIELD(CBondInfoImpl, m_sAuction_Unit, true);
  m_sAuction_Unit = sUnit;
}

const char* CBondInfoImpl::GetRemainPeriod(time_t tNow) {
  USE_FIELD(CBondInfoImpl, m_sRemainDateDisplay, false);
  if (IsEmpty(m_sRemainDateDisplay)) {
    char sRemain[MAX_PATH];
    (const_cast<CBondInfoImpl*>(this))
        ->CalcRemainPeriodNew(tNow, sRemain, MAX_PATH, true);

    USE_FIELD_ADD(CBondInfoImpl, m_sRemainDate, true);
    USE_FIELD_ADD(CBondInfoImpl, m_sRemainDateDisplay, true);
    bool bench_log = false;  // = BOOLTEST(kProfileBenchLog);
    if (bench_log && strcmp(m_sRemainDateDisplay, sRemain) !=
                         0)  // && strcmp(sRemain, g_strRemainPeriod) != 0)
    {
      char sRemainOld[MAX_PATH];
      memset(sRemainOld, 0, sizeof(sRemainOld));
      FIELDCOPY(sRemainOld, m_sRemainDateDisplay);
      LOGDEBUG(
          "CalcRemainPeriodNew different result, <%s, %s, old = \"%s\", new = "
          "\"%s\"",
          GetCombBondCode(), GetBondShortName(), sRemainOld, sRemain);
    }
    m_sRemainDate = sRemain;
    m_sRemainDateDisplay = sRemain;
  }
  return m_sRemainDateDisplay;
}

const char* CBondInfoImpl::GetRemainPeriodByIntTime(int tNow) {
  if (IsEmpty(m_sRemainDateDisplay)) {
    char sRemain[MAX_PATH];
    (const_cast<CBondInfoImpl*>(this))
        ->CalcRemainPeriodNew(tNow, sRemain, MAX_PATH, true, true);
    m_sRemainDate = sRemain;
    m_sRemainDateDisplay = sRemain;
  }
  return m_sRemainDateDisplay;
}

std::string CBondInfoImpl::GetHistoryRemainPeriod(time_t tDay) const {
  char sRemain[MAX_PATH];
  (const_cast<CBondInfoImpl*>(this))
      ->CalcRemainPeriodNew(tDay, sRemain, MAX_PATH, false);
  return std::string(sRemain);
}

void CBondInfoImpl::CalcRemainPeriodNew(time_t tNow, char* sRemain, int strLen,
                                        bool checkOutstandingAmount,
                                        bool useIntTime) {
  USE_FIELD(CBondInfoImpl, m_sCombBondKey, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityDate, false);

  int Today = 0;
  if (!useIntTime && tNow > 0) {
    struct tm* tmNow = localtime(&tNow);
    Today = (tmNow->tm_year + 1900) * 10000 + (tmNow->tm_mon + 1) * 100 +
            tmNow->tm_mday;
  } else
    Today = tNow;

  {  // 如果不到起息日，从起息日开始计算
    int startDate = atoi(m_sInterestStartDate);
    Today = qMax(Today, startDate);
  }

  memset(sRemain, 0, strLen * sizeof(char));
  char sOption[MAX_PATH];
  const char* expStr = strBondLib_Expired();
  do {
    USE_FIELD_ADD(CBondInfoImpl, m_sMarketType, false);

    int nMarketType = atoi(m_sMarketType);
    if (nMarketType != 1 && nMarketType != 2) {  // 无效债券。剩余期限为空
      break;
    }
    if (checkOutstandingAmount) {
      USE_FIELD_ADD(CBondInfoImpl, m_fOutstandingAmount, false);
      USE_FIELD_ADD(CBondInfoImpl, m_fActualIssueAmount, false);
      if (m_fOutstandingAmount < 0.00001 &&
          m_fActualIssueAmount > 0.00001) {  // 未偿还金额=0时，处理方法
        if (nMarketType == 2 &&
            !IsAddIssueBond()) {  // 二级债券，并且非增续发券
#if WIN32
          strcpy_s(sRemain, strLen, strBondLib_Expired());  // 已到期
#else
          strcpy(sRemain, expStr);
#endif
          break;
        }
      }
    }
    int maturityDate = atoi(m_sMaturityDate);
    if (maturityDate <= 0) {  // 到期日为空，剩余期限为空
      break;
    }

    int optionIndex = GetOptionInfoIndex();
    bool bPRS = false;
    if (optionIndex >= 0) {
      const CBondOptionInfo* pOpi =
          CBondContainer::instance().GetBondOptionInfo(optionIndex);
      if (strcmp(pOpi->GetCombBondKey(), m_sCombBondKey) == 0) {
        if (strstr(pOpi->GetOptionType_(), "PRS") != 0) {
          if (m_nPayDate > 19000000) {
            maturityDate = m_nPayDate;  // 实际兑付日
            bPRS = true;
          }
        }
      }
    }

    if (Today > maturityDate) {
#if WIN32
      strcpy_s(sRemain, strLen, strBondLib_Expired());  // 已到期
#else
      strcpy(sRemain, expStr);
#endif
      break;
    }

    std::set<int> setOption;
    do {
      int optionIndex = GetOptionInfoIndex();
      if (optionIndex < 0) break;
      const CBondOptionInfo* pOpi =
          CBondContainer::instance().GetBondOptionInfo(optionIndex);
      if (!pOpi) break;
      int ret = strcmp(pOpi->GetCombBondKey(), m_sCombBondKey);
      BASSERT(ret == 0);
      if (ret != 0) break;

      const char* callstr = pOpi->GetCallStr();
      const char* putstr = pOpi->GetPutStr();

      std::vector<std::string> vctOption;
      _split(vctOption, callstr, "|");
      if (vctOption.size() > 0) {
        for (int i = 0; i < (int)vctOption.size(); i += 2) {
          int nOptDate = atoi(vctOption[i].c_str());
          if (nOptDate > Today) setOption.insert(nOptDate);
        }
      }
      vctOption.clear();
      _split(vctOption, putstr, "|");
      if (vctOption.size() > 0) {
        for (int i = 0; i < (int)vctOption.size(); i += 2) {
          int nOptDate = atoi(vctOption[i].c_str());
          if (nOptDate > Today) setOption.insert(nOptDate);
        }
      }
    } while (0);

    // 到期日
    setOption.insert(maturityDate);

    bool isFirst = true;
    for (auto& optDate : setOption) {
      if (Today > optDate) continue;

      memset(sOption, 0, sizeof(sOption));
      _splitdate(Today, optDate, sOption, MAX_PATH, isFirst);
      _strcat(sRemain, sOption);
      if (isFirst) isFirst = strlen(sRemain) == 0;
      Today = optDate;
    }

    USE_FIELD_ADD(CBondInfoImpl, m_sOptionType, false);
    if (!isFirst && strcmp(m_sOptionType, "ETS") == 0)  // 可续期券判断逻辑
    {
      _strcat(sRemain, "N");
    }
  } while (0);
}

void CBondInfoImpl::CalcRemainPeriod(time_t tNow) {
  // 延迟计算,非const
  // 读取:
  // m_sMaturityDate
  // 写入:
  // g_strRemainPeriod
  // m_sRemainDate
  // m_sRemainDateDisplay

  const char* pStartDate = GetInterestStartDate();
  if (tNow <= 0) tNow = time(0);
  if (strlen(pStartDate) == 8) {
    char sy[5] = {0};
    memcpy(sy, pStartDate, 4);
    char sm[3] = {0};
    memcpy(sm, pStartDate + 4, 2);
    char sd[3] = {0};
    memcpy(sd, pStartDate + 6, 2);
    struct tm tmq;
    tmq.tm_year = atoi(sy) - 1900;
    tmq.tm_mon = atoi(sm) - 1;
    tmq.tm_mday = atoi(sd);
    tmq.tm_hour = 8;
    tmq.tm_min = 0;
    tmq.tm_sec = 0;
    time_t tq = mktime(&tmq);
    if (tNow < tq) tNow = tq;
  }

  const char* pMaturityDate = m_sMaturityDate;
  if (IsEmpty(pMaturityDate)) {
    m_sRemainDate = "";
    m_sRemainDateDisplay = "";
    return;
  }
  char g_strRemainPeriod[MAX_PATH] = {0};
  memset(g_strRemainPeriod, 0, MAX_PATH * sizeof(char));
  FIELDCOPY(g_strRemainPeriod, strBondLib_Expired());  // "已到期"
  char sYear[5] = {0}, sMonth[3] = {0}, sDay[3] = {0};
  memset(sYear, 0, 5);
  memset(sMonth, 0, 3);
  memset(sDay, 0, 3);
  memcpy(sYear, pMaturityDate, 4);
  memcpy(sMonth, pMaturityDate + 4, 2);
  memcpy(sDay, pMaturityDate + 6, 2);
  struct tm tmExpiry;
  memset(&tmExpiry, 0, sizeof(tm));
  tmExpiry.tm_year = atoi(sYear) - 1900;
  tmExpiry.tm_mon = atoi(sMonth) - 1;
  tmExpiry.tm_mday = atoi(sDay);
  tmExpiry.tm_hour = 8;
  tmExpiry.tm_min = 0;
  tmExpiry.tm_sec = 0;

  struct tm* tmNow = localtime(&tNow);
  if (tmNow == NULL) {
    m_sRemainDate = "";
    m_sRemainDateDisplay = "";
    return;
  }
  tmNow->tm_hour = 8;
  tmNow->tm_min = 0;
  tmNow->tm_sec = 0;
  tNow = mktime(tmNow);

  time_t tExpiry = mktime(&tmExpiry);
  if (tNow > tExpiry) {
    m_sRemainDate = g_strRemainPeriod;
    m_sRemainDateDisplay = m_sRemainDate;
    return;
  }

  bool isOption = false;
  int nRemain = 0;
  const char* pTermToMaturity = m_sTermToMaturity;
  int nLen = strlen(pTermToMaturity);
  if (nLen > 0) {
    const char* pDest = strchr(pTermToMaturity, '+');
    if (pDest) {
      char sLeft[16] = {0}, sRight[16] = {0};
      memset(sLeft, 0, 16);
      memset(sRight, 0, 16);
      memcpy(sLeft, pTermToMaturity, pDest - pTermToMaturity);
      pDest++;
      int l = nLen - (pDest - pTermToMaturity);
      if (l > 0) {
        memcpy(sRight, pDest, l);
        int nLeft = atoi(sLeft);
        int nRight = atoi(sRight);
        if (nLeft > 0 && nRight > 0) {
          struct tm tmExpiry1 = tmExpiry;
          tmExpiry1.tm_year -= nRight;
          time_t tExpiry1 = mktime(&tmExpiry1);
          if (tExpiry1 > tNow) {
            nRemain = nRight;
            tmExpiry = tmExpiry1;
            isOption = true;
          }
        }
      }
    }
  }

  int nRemain2 = 0;
  struct tm tmExpiry1;
  memcpy(&tmExpiry1, &tmExpiry, sizeof(tmExpiry));
  tmExpiry1.tm_year--;
  if (tmExpiry1.tm_mon == 1 && tmExpiry1.tm_mday == 29) {
    tmExpiry1.tm_mday = 28;
  }
  time_t tExpiry1 = mktime(&tmExpiry1);
  while (tExpiry1 > tNow) {
    tmExpiry.tm_year = tmExpiry1.tm_year;
    nRemain2++;
    tmExpiry1.tm_year--;
    tExpiry1 = mktime(&tmExpiry1);
  }
  if (((tmExpiry.tm_year) % 4 != 0 ||
       ((tmExpiry.tm_year % 100) == 0 && (tmExpiry.tm_year % 400) != 0)) &&
      tmExpiry.tm_mon == 1 && tmExpiry.tm_mday == 29) {
    tmExpiry.tm_mday = 28;
  }

  tExpiry = mktime(&tmExpiry);
  int nYDay = (tExpiry - tNow) / (60 * 60 * 24);
  if (nRemain2 == 0) {
    if (isOption) {
      FMTBUF(g_strRemainPeriod, "%dD+%dY", nYDay, nRemain);
    } else {
      FMTBUF(g_strRemainPeriod, "%dD", nYDay);
    }
  } else if (nRemain2 > 0) {
    if (nYDay == 0) {
      FMTBUF(g_strRemainPeriod, "%dY+%dY", nRemain2, nRemain);
    } else {
      float fYear = (float)nRemain2;
      memcpy(&tmExpiry1, &tmExpiry, sizeof(tmExpiry));
      tmExpiry1.tm_year--;
      time_t tExpiry2 = mktime(&tmExpiry1);
      int nDay = (tExpiry - tExpiry2) / (60 * 60 * 24);
      fYear += (float)nYDay / nDay;
      if (isOption) {
        FMTBUF(g_strRemainPeriod, "%.2fY+%dY", fYear, nRemain);
      } else {
        FMTBUF(g_strRemainPeriod, "%.2fY", fYear);
      }
    }
  }

  USE_FIELD_ADD(CBondInfoImpl, m_sOptionType, false);
  m_sRemainDate = g_strRemainPeriod;
  if (strcmp(m_sOptionType, "ETS") == 0)  // 可续期券判断逻辑
  {
    std::string temp = std::string(g_strRemainPeriod) + std::string("+N");
    m_sRemainDateDisplay = temp.c_str();
  } else
    m_sRemainDateDisplay = m_sRemainDate;
  return;
}

float CBondInfoImpl::GetRemainYear(time_t tNow) const {
  USE_FIELD(CBondInfoImpl, m_sMaturityDate, false);
  if (tNow < 0) tNow = time(0);

  const char* pStartDate = GetInterestStartDate();
  if (strlen(pStartDate) == 8) {
    char sy[5] = {0};
    memcpy(sy, pStartDate, 4);
    char sm[3] = {0};
    memcpy(sm, pStartDate + 4, 2);
    char sd[3] = {0};
    memcpy(sd, pStartDate + 6, 2);
    struct tm tmq;
    tmq.tm_year = atoi(sy) - 1900;
    tmq.tm_mon = atoi(sm) - 1;
    tmq.tm_mday = atoi(sd);
    tmq.tm_hour = 8;
    tmq.tm_min = 0;
    tmq.tm_sec = 0;
    time_t tq = mktime(&tmq);
    if (tNow < tq) tNow = tq;
  }
  const char* pMaturityDate = m_sMaturityDate;
  if (IsEmpty(pMaturityDate)) {
    return -1.f;  // 到期日为空
  }
  char sYear[5] = {0}, sMonth[3] = {0}, sDay[3] = {0};
  memset(sYear, 0, 5);
  memset(sMonth, 0, 3);
  memset(sDay, 0, 3);
  memcpy(sYear, pMaturityDate, 4);
  memcpy(sMonth, pMaturityDate + 4, 2);
  memcpy(sDay, pMaturityDate + 6, 2);
  struct tm tmExpiry;
  memset(&tmExpiry, 0, sizeof(tm));
  tmExpiry.tm_year = atoi(sYear) - 1900;
  tmExpiry.tm_mon = atoi(sMonth) - 1;
  tmExpiry.tm_mday = atoi(sDay);
  tmExpiry.tm_hour = 8;
  tmExpiry.tm_min = 0;
  tmExpiry.tm_sec = 0;

  struct tm* tmNow = localtime(&tNow);
  if (tmNow == NULL) {
    return -1.f;  // 参数错误
  }
  tmNow->tm_hour = 8;
  tmNow->tm_min = 0;
  tmNow->tm_sec = 0;
  tNow = mktime(tmNow);

  time_t tExpiry = mktime(&tmExpiry);
  if (tNow > tExpiry) {
    return -1.f;  // 已到期
  }

  int nRemain = 0;
  struct tm tmExpiry1;
  memcpy(&tmExpiry1, &tmExpiry, sizeof(tmExpiry));
  tmExpiry1.tm_year--;
  if (tmExpiry1.tm_mon == 1 && tmExpiry1.tm_mday == 29) {
    tmExpiry1.tm_mday = 28;
  }
  time_t tExpiry1 = mktime(&tmExpiry1);
  while (tExpiry1 > tNow) {
    tmExpiry.tm_year = tmExpiry1.tm_year;
    nRemain++;
    tmExpiry1.tm_year--;
    tExpiry1 = mktime(&tmExpiry1);
  }
  if (((tmExpiry.tm_year) % 4 != 0 ||
       ((tmExpiry.tm_year % 100) == 0 && (tmExpiry.tm_year % 400) != 0)) &&
      tmExpiry.tm_mon == 1 && tmExpiry.tm_mday == 29) {
    tmExpiry.tm_mday = 28;
  }

  tExpiry = mktime(&tmExpiry);
  int nYDay = (tExpiry - tNow) / (60 * 60 * 24);
  int nDay = (tExpiry - tExpiry1) / (60 * 60 * 24);
  float fYear = (float)nRemain;
  fYear += (float)nYDay / nDay;
  return fYear;
}

float CBondInfoImpl::GetRemainYearToOption(time_t tNow) const {
  USE_FIELD(CBondInfoImpl, m_sOptionDate, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityDate, false);
  if (tNow < 0) tNow = time(0);
  char sEndDate[16] = {0};
  memset(sEndDate, 0, sizeof(char) * 16);
  const char* pStartDate = GetInterestStartDate();
  if (strlen(pStartDate) == 8) {
    char sy[5] = {0};
    memcpy(sy, pStartDate, 4);
    char sm[3] = {0};
    memcpy(sm, pStartDate + 4, 2);
    char sd[3] = {0};
    memcpy(sd, pStartDate + 6, 2);
    struct tm tmq;
    tmq.tm_year = atoi(sy) - 1900;
    tmq.tm_mon = atoi(sm) - 1;
    tmq.tm_mday = atoi(sd);
    tmq.tm_hour = 8;
    tmq.tm_min = 0;
    tmq.tm_sec = 0;
    time_t tq = mktime(&tmq);
    if (tNow < tq) tNow = tq;
  }

  const char* pOptionDate = m_sOptionDate;
  if (IsEmpty(pOptionDate)) {
    const char* pMaturityDate = m_sMaturityDate;
    if (IsEmpty(pMaturityDate)) {
      return -1.f;  // 到期日为空
    } else
      FIELDCOPY(sEndDate, pMaturityDate);
  } else {
    FIELDCOPY(sEndDate, pOptionDate);
  }
  char sYear[5] = {0}, sMonth[3] = {0}, sDay[3] = {0};
  memset(sYear, 0, 5);
  memset(sMonth, 0, 3);
  memset(sDay, 0, 3);
  memcpy(sYear, sEndDate, 4);
  memcpy(sMonth, sEndDate + 4, 2);
  memcpy(sDay, sEndDate + 6, 2);
  struct tm tmExpiry;
  memset(&tmExpiry, 0, sizeof(tm));
  tmExpiry.tm_year = atoi(sYear) - 1900;
  tmExpiry.tm_mon = atoi(sMonth) - 1;
  tmExpiry.tm_mday = atoi(sDay);
  tmExpiry.tm_hour = 8;
  tmExpiry.tm_min = 0;
  tmExpiry.tm_sec = 0;

  struct tm* tmNow = localtime(&tNow);
  if (tmNow == NULL) {
    return -1.f;  // 参数错误
  }
  tmNow->tm_hour = 8;
  tmNow->tm_min = 0;
  tmNow->tm_sec = 0;
  tNow = mktime(tmNow);

  time_t tExpiry = mktime(&tmExpiry);
  if (tNow > tExpiry) {
    return -1.f;  // 已到期
  }

  int nRemain = 0;
  struct tm tmExpiry1;
  memcpy(&tmExpiry1, &tmExpiry, sizeof(tmExpiry));
  tmExpiry1.tm_year--;
  if (tmExpiry1.tm_mon == 1 && tmExpiry1.tm_mday == 29) {
    tmExpiry1.tm_mday = 28;
  }
  time_t tExpiry1 = mktime(&tmExpiry1);
  while (tExpiry1 > tNow) {
    tmExpiry.tm_year = tmExpiry1.tm_year;
    nRemain++;
    tmExpiry1.tm_year--;
    tExpiry1 = mktime(&tmExpiry1);
  }
  if (((tmExpiry.tm_year) % 4 != 0 ||
       ((tmExpiry.tm_year % 100) == 0 && (tmExpiry.tm_year % 400) != 0)) &&
      tmExpiry.tm_mon == 1 && tmExpiry.tm_mday == 29) {
    tmExpiry.tm_mday = 28;
  }

  tExpiry = mktime(&tmExpiry);
  int nYDay = (tExpiry - tNow) / (60 * 60 * 24);
  int nDay = (tExpiry - tExpiry1) / (60 * 60 * 24);
  float fYear = (float)nRemain;
  fYear += (float)nYDay / nDay;
  return fYear;
}

void CBondInfoImpl::SetWarrant(const char* sWarrant) {
  USE_FIELD(CBondInfoImpl, m_sWarrant, true);
  m_sWarrant = sWarrant;
}

void CBondInfoImpl::SetQuotTopflag(int tp) {
  USE_FIELD(CBondInfoImpl, m_flag, true);
  m_flag.SetStickFlag(tp);
}

bool CBondInfoImpl::IsNewBond() const  // 是否新发债
{
  USE_FIELD(CBondInfoImpl, m_sListDate, false);
  if (IsEmpty(m_sListDate)) return false;

  time_t svTime = ServerTimeMgr::instance().serverTime();
  LONG lDate = atol(m_sListDate);
  int nYear, nMonth, nDay;
  nYear = lDate / 10000;
  nMonth = (lDate % 10000) / 100;
  nDay = lDate % 100;
  if (nDay < 1 || nDay > 31) return false;
  if (nMonth < 1 || nMonth > 12) return false;
  if (nYear < 1900) return false;
  QDateTime listedDate = QDate(nYear, nMonth, nDay).startOfDay();
  QDateTime nowDate = QDateTime::currentDateTime();
  if (nowDate < listedDate) return false;
  if (listedDate.daysTo(nowDate) > 5) return false;
  return true;
}

bool CBondInfoImpl::GetQuotTopflag() const  // 债券是否置顶
{
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetStickFlag();
}

bool CBondInfoImpl::IsWarranted() const  // 债券是否担保
{
  USE_FIELD(CBondInfoImpl, m_sWarrant, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sBondSubType, false);
  const char* pWarrant = m_sWarrant;
  if (NULL != strstr(pWarrant, "GUA")      // 担保人
      || NULL != strstr(pWarrant, "SEC"))  // 担保物
  {
    return true;
  }

  QBCRMBond& cb = QBCRMBond::instance();
  if (cb.GetBondByReferKey(GetCombBondKey()) != NULL) return true;

  return false;
}

bool CBondInfoImpl::IsRight() const  // 是否权证
{
  USE_FIELD(CBondInfoImpl, m_sRemainDateDisplay, false);
  if (IsETSBond()) return true;  // 永续债认为是含权
  if (strchr(m_sRemainDateDisplay, '+') != NULL) return true;
  return false;
  // 	USE_FIELD(CBondInfoImpl, m_sTermToMaturity, false);
  //     //option_type值初始录了不改变，行权日过后变成不含权债券
  // 	if (IsETSBond())
  // 	{//永续债认为是含权
  // 		return true;
  // 	}
  // 	if(IsEmpty(m_sTermToMaturity))
  // 		return false;
  // 	return true;
}

bool CBondInfoImpl::IsRebated() const  // 债券是否一级半，新发债
{
  USE_FIELD(CBondInfoImpl, m_sMarketType, false);
  if (strcmp(m_sMarketType, "1") != 0) return false;
  return true;
}

bool CBondInfoImpl::IsMortgage() const  // 债券是否可质押
{
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return ('Y' == m_flag.GetMortgageFlag() || 'y' == m_flag.GetMortgageFlag());
}

bool CBondInfoImpl::IsCrossMarket() const  // 债券是否跨市场
{
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return ('Y' == m_flag.GetCrossmarketFlag() ||
          'y' == m_flag.GetCrossmarketFlag());
}

bool CBondInfoImpl::IsSOEenterType() const  // 债券是否国企债
{
  USE_FIELD(CBondInfoImpl, m_sInstitutionType, false);
  if (strcmp(m_sInstitutionType, "SOE") != 0) return false;
  return true;
}

bool CBondInfoImpl::IsMunicipal() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return ('Y' == m_flag.GetMunicipalFlag() || 'y' == m_flag.GetMunicipalFlag());
}

bool CBondInfoImpl::IsRatingDebt() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "BGB") == 0 ||
      strcmp(m_sBondSubType, "SGB") == 0 ||
      strcmp(m_sBondSubType, "EGB") == 0 ||
      strcmp(m_sBondSubType, "SCB") == 0 ||
      strcmp(m_sBondSubType, "TLB") == 0 ||
      strcmp(m_sBondSubType, "LLB") == 0 ||
      strcmp(m_sBondSubType, "PBB") == 0) {
    return true;
  } else {
    return false;
  }
}

// bool	CBondInfo::IsValidBond( ) const		// 债券信息是否正确
// {
// 	return m_bIsValid;
//
// //  下面判断效率很慢，由于此函数会频繁调用
// // 	if( NULL == m_sBondKey || IsEmpty(m_sBondKey) )
// // 	{
// // 		return false;
// // 	}
// // 	return true;
// }

bool CBondInfoImpl::IsExpireBond() const {  // 已过期债券
  USE_FIELD(CBondInfoImpl, m_sMaturityDate, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sRemainDate, false);
  if (IsEmpty(m_sMaturityDate)) return false;
  if (strcmp(m_sRemainDate, strBondLib_Expired() /*"已到期"*/) == 0)
    return true;
  return false;
}

bool CBondInfoImpl::IsInterbank() const {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sListedMarket, CBondContainer::lmCIB) == 0) return true;
  return false;
}

bool CBondInfoImpl::IsExchange() const {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sListedMarket, CBondContainer::lmSSE) == 0 ||
      strcmp(m_sListedMarket, CBondContainer::lmSZE) == 0)
    return true;
  return false;
}

bool CBondInfoImpl::IsSSEBond() const {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sListedMarket, CBondContainer::lmSSE) == 0) return true;
  return false;
}

bool CBondInfoImpl::IsSZEBond() const {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sListedMarket, CBondContainer::lmSZE) == 0) return true;
  return false;
}

bool CBondInfoImpl::IsBSEBond() const {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, false);
  if (strcmp(m_sListedMarket, CBondContainer::lmBSE) == 0) return true;
  return false;
}

bool CBondInfoImpl::IsFinanceBond() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PBB") == 0) {
    return true;
  }
  return false;
}

bool CBondInfoImpl::IsCNYBond() const {
  USE_FIELD(CBondInfoImpl, m_sCurrency, false);
  if (qstricmp(m_sCurrency, "CNY") == 0) {
    return true;
  }
  return false;
}

int CBondInfoImpl::DigitBit() const { return 2; }

bool CBondInfoImpl::MatchJianpin(const char* pstr) const {
  const char* pdest = strstr(GetBondJianpin().c_str(), pstr);
  if (pdest != NULL) return true;
  return false;
}

bool CBondInfoImpl::MatchQuanpin(const char* pstr) const {
  std::string quanpin = GetBondQuanpin();
  if (quanpin.empty() || pstr == NULL) return false;
  const char* pdest = strstr(quanpin.c_str(), pstr);
  return (pdest != NULL) ? true : false;
}

bool CBondInfoImpl::CheckBondTypeNew(
    const BLHCONDITION& Cond) const  // 判断产品类型，5.5.3新版筛选，最优报价
{
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::newBondNone) return false;
    if (CheckBondTypeNew(Cond.nTypeNew[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckBondTypeNew(UINT nSubType) const {
  switch (nSubType) {
    case CBondContainer::newBondNone:
      return false;
      break;
    case CBondContainer::newBondAll:
      return true;
      break;
    case CBondContainer::newBondCountry:  // 国债
      return IsBondCountry();
      break;
    case CBondContainer::newBondCenter:  // 央票
      return IsBondCenter();
      break;
    case CBondContainer::newBondCDB:  // 国开
      return IsBondGKZ();
      break;
    case CBondContainer::newBondFinance:  // 政金债
      return IsBondFinance();
      break;
    case CBondContainer::newBondAgDp:  // 农发
      return IsBondAgDev();
      break;
    case CBondContainer::newBondInAndEx:  // 口行
      return IsBondInAndEx();
      break;
    case CBondContainer::newBondLocal:  // 地方债
      return IsBondLocal();
      break;

      ////短融
    case CBondContainer::newBondShort:  // 短融
      return IsBondShort();
      break;
    case CBondContainer::newBondShort_Short:  // 短融
      return IsBondShort_S();
      break;
    case CBondContainer::newBondShort_Super:  // 超短融
      return IsBondCShort();
      break;
      //////////////////////////////////////////////////////////////////////////

    case CBondContainer::newBondMTN:  // 中票
      return IsBondMTN();
      break;
    case CBondContainer::newBondEnterpr:  // 企业债
      return IsBondEnterpr();
      break;

      ////公司债
    case CBondContainer::newBondCOP:  // 公司债
      return IsBondCOP();
      break;
    case CBondContainer::newBondCOP_Null:  // 公募
      return IsBondCOP() && CheckAssetStatus(CBondContainer::AssetNull);
      break;
    case CBondContainer::newBondCOP_Pub:  // 小公募
      return IsBondCOP() && CheckAssetStatus(CBondContainer::AssetPub);
      break;
    case CBondContainer::newBondCOP_Pri:  // 私募
      return IsBondCOP() && CheckAssetStatus(CBondContainer::AssetPri);
      break;
      //////////////////////////////////////////////////////////////////////////

      ////商金债
    case CBondContainer::newBondBank:  // 商金债
      return IsBondBank();
      break;
    case CBondContainer::newBondBank_Commercial:  // 商业银行债
      return IsBondCommercialBank();
      break;
    case CBondContainer::newBondBank_Second:  // 银行二级债
      return IsBondBankSecond();
      break;
    case CBondContainer::newBondBank_Perpetual:  // 银行永续债
      return IsBondBankPerpetual();
      break;
      //////////////////////////////////////////////////////////////////////////

      ////券商债
    case CBondContainer::newBondBroker:  // 券商债
      return IsBondBroker();
      break;
    case CBondContainer::newBondBroker_Corp:  // 证券公司
      return IsBondBroker_Corp();
      break;
    case CBondContainer::newBondBroker_Short:  // 证券公司短融
      return IsBondBroker_Short();
      break;
    case CBondContainer::newBondBroker_Second:  // 证券次级
      return IsBondBroker_Second();
      break;
      //////////////////////////////////////////////////////////////////////////

    case CBondContainer::newBondInsurance:  // 保险债
      return IsBondInsurance();
      break;
    case CBondContainer::newBondFinancialOther:  // 其他金融债
      return IsBondFinancialOther();
      break;
    case CBondContainer::newBondPPN:
      return IsBondPPN();
      break;
    case CBondContainer::newBondNCD:
      return IsBondNCD();
      break;
    case CBondContainer::newBondABS:
      return IsBondABS();
      break;
    case CBondContainer::newBondConvertible:  // 可转债
      return IsTransBond();
      break;
    case CBondContainer::newBondRailway:  // 铁道债
      return IsBondRailway();
      break;
    case CBondContainer::newBondOther:
      if (IsBondCountry() || IsFinanceBond() || IsBondLocal() ||
          IsBondShort() || IsBondMTN() || IsBondEnterpr() || IsBondCOP() ||
          IsBondBank() || IsBondBroker() || IsBondInsurance() ||
          IsBondFinancialOther() || IsBondPPN() || IsBondNCD() || IsBondABS() ||
          IsTransBond() || IsBondRailway())
        return false;
      else
        return true;
      break;
    default:
      return false;
      break;
  }
  return false;
}

bool CBondInfoImpl::CheckCmbcBondType(BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::CmbcBondNone) {
      return false;
    }

    if (CheckCmbcBondType(Cond.nTypeNew[i])) {
      return true;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckBjrcbBondType(BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::BondSC_None) {
      return false;
    }

    if (CheckBjrcbBondType(Cond.nTypeNew[i])) {
      return true;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckNbcbCDBondType(BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::NbcbBondNone) {
      return false;
    }

    if (CheckNbcbCDBondType(Cond.nTypeNew[i])) {
      return true;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckNbcbIRDBondType(BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::BondSC_None) {
      return false;
    }

    if (CheckNbcbIRDBondType(Cond.nTypeNew[i])) {
      return true;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckNbcbIssueBondType(BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::BondSC_None) {
      return false;
    }

    if (CheckNbcbIssueBondType(Cond.nTypeNew[i])) {
      return true;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckCmbcBondType(uint32_t nSubType) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  switch (nSubType) {
    case CBondContainer::CmbcBondNone:
      return false;
      break;
    case CBondContainer::CmbcBondAll:
      return true;
      break;
    case CBondContainer::CmbcBondFinance:
      if (strcmp(m_sBondSubType, "PBB") == 0) return true;
      break;
    case CBondContainer::CmbcBondShort:
      if (IsBondShort()) {
        return true;
      } else {
        return false;
      }
      // if(strcmp(m_sBondSubType, "LCP")==0)return true;
      // else if(strcmp(m_sBondSubType, "SSB")==0)return true;
      // else if(strcmp(m_sBondSubType, "CCP")==0)return true;
      // else if(strcmp(m_sBondSubType, "CSP")==0)return true;
      // else if(strcmp(m_sBondSubType, "LSP")==0)return true;
      break;
    case CBondContainer::CmbcBondChina:
      if (IsBondChina()) {
        return true;
      } else {
        return false;
      }
      // if(strcmp(m_sBondSubType, "LMN")==0)return true;
      // else if(strcmp(m_sBondSubType, "CMN")==0)return true;
      break;
    case CBondContainer::CmbcBondPrivateDebet: {
      if (IsBondNonPublicCor() || IsBondPPN()) {
        return true;
      } else {
        return false;
      }
    }
    // if(IsPrivateDebet())return true;
    break;
    default:
      return false;
      break;
  }
  return false;
}

bool CBondInfoImpl::CheckBjrcbBondType(uint32_t nSubType) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  switch (nSubType) {
    case CBondContainer::BondSC_None:
      return false;
      break;
    case CBondContainer::BondSC_All:
      return true;
      break;
    case CBondContainer::BondSC_Country:
      if (strcmp(m_sBondSubType, "BGB") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "SGB") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "EGB") == 0)
        return true;
      break;
    case CBondContainer::BondSC_Finance:
      if (strcmp(m_sBondSubType, "PBB") == 0) return true;
      break;
    case CBondContainer::BondSC_Short:
      if (strcmp(m_sBondSubType, "LCP") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "SSB") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "CCP") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "CSP") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "LSP") == 0)
        return true;
      break;
    case CBondContainer::BondSC_China:
      if (strcmp(m_sBondSubType, "LMN") == 0)
        return true;
      else if (strcmp(m_sBondSubType, "CMN") == 0)
        return true;
      break;
    case CBondContainer::BondSC_ABS:
      if (IsBondABS()) return true;
      break;
    case CBondContainer::BondSC_PPN:
      if (IsBondPPN()) return true;
      break;
    default:
      return false;
      break;
  }
  return false;
}

bool CBondInfoImpl::CheckNbcbCDBondType(uint32_t nSubType) const {
  switch (nSubType) {
    case CBondContainer::NbcbBondNone:
      return false;
      break;
    case CBondContainer::NbcbBondAll:
      return true;
      break;
    case CBondContainer::NbcbBondShort:  // 短融
      return IsBondShort_S();
      break;
    case CBondContainer::NbcbBondSuperShort:  // 超短融
      return IsBondCShort();
      break;
    case CBondContainer::NbcbBondChina:  // 中票
      return IsBondChina();
      break;
    case CBondContainer::NbcbBondEnterpr:  // 企业债
      return IsBondEnterpr();
      break;
    case CBondContainer::NbcbBondCOP:  // 公司债
      return IsBondCOP();
      break;
    case CBondContainer::NbcbBondSecond:  // 二级资本债
      return IsBondSecondCapital();
      break;
    case CBondContainer::NbcbBondPDB:  // 熊猫债
      return IsBondPDB();
      break;
    case CBondContainer::NbcbBondNCD:  // NCD
      return IsBondNCD();
      break;
    case CBondContainer::NbcbBondPPN:  // PPN
      return IsBondPPN();
      break;
    case CBondContainer::NbcbBondABS:  // ABS
      return IsBondABS();
      break;
    case CBondContainer::NbcbBondOther:  // 其它
      return !IsBondShort_S() && !IsBondCShort() && !IsBondChina() &&
             !IsBondEnterpr() && !IsBondCOP() && !IsBondSecondCapital() &&
             !IsBondPDB() && !IsBondNCD() && !IsBondPPN() && !IsBondABS();
      break;
    default:
      return false;
      break;
  }

  return false;
}

bool CBondInfoImpl::CheckNbcbIRDBondType(uint32_t nSubType) const {
  switch (nSubType) {
    case CBondContainer::NbcbIRDBondNone:
      return false;
      break;
    case CBondContainer::NbcbIRDBondAll:
      return true;
      break;
    case CBondContainer::NbcbIRDBondCountry:  // 国债
      return IsBondCountry();
      break;
    case CBondContainer::NbcbIRDBondCDB:  // 国开
      return IsBondGKZ();
      break;
    case CBondContainer::NbcbIRDBondLocal:  // 地方债
      return IsBondLocal();
      break;
    case CBondContainer::NbcbIRDBondOther:
      return !IsBondCountry() && !IsBondGKZ() && !IsBondLocal();
      break;
    default:
      return false;
      break;
  }

  return false;
}

bool CBondInfoImpl::CheckNbcbIssueBondType(uint32_t nSubType) const {
  switch (nSubType) {
    case CBondContainer::BondC_None:
      return false;
      break;
    case CBondContainer::BondC_All:
      return true;
      break;
    case CBondContainer::BondC_Country:  // 国债
      return IsBondCountry();
      break;
    case CBondContainer::BondC_Finance:  // 金融债
      return IsBondFinance();
      break;
    case CBondContainer::BondC_Local:  // 地方债
      return IsBondLocal();
      break;
    case CBondContainer::BondC_Short:  // 短融
      return IsBondShort_S();
      break;
    case CBondContainer::BondC_CShort:  // 超短融
      return IsBondCShort();
      break;
    case CBondContainer::BondC_China:  // 中票
      return IsBondChina();
      break;
    case CBondContainer::BondC_Enterpr:  // 企业债
      return IsBondEnterpr();
      break;
    case CBondContainer::BondC_COP:  // 公司债
      return IsBondCOP();
      break;
    case CBondContainer::BondC_Second:  // 二级资本债
      return IsBondSecondCapital();
      break;
    case CBondContainer::BondC_PDB:  // 熊猫债
      return IsBondPDB();
      break;
    case CBondContainer::BondC_NCD:  // NCD
      return IsBondNCD();
      break;
    case CBondContainer::BondC_PPN:  // PPN
      return IsBondPPN();
      break;
    case CBondContainer::BondC_ABS:  // ABS
      return IsBondABS();
      break;
    case CBondContainer::BondC_Other:  // 其它
      return !IsBondCountry() && !IsBondFinance() && !IsBondLocal() &&
             !IsBondShort_S() && !IsBondCShort() && !IsBondChina() &&
             !IsBondEnterpr() && !IsBondCOP() && !IsBondSecondCapital() &&
             !IsBondPDB() && !IsBondNCD() && !IsBondPPN() && !IsBondABS();
      break;
    default:
      return false;
      break;
  }

  return false;
}

bool CBondInfoImpl::ShortCheckBondType(const BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::BondSC_None) return false;
    if (ShortCheckBondType(Cond.nTypeNew[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::ShortCheckBondType(uint32_t nSubType) const {
  bool bRet = false;
  switch (nSubType) {
    case CBondContainer::BondSC_None:
      return false;
      break;
    case CBondContainer::BondSC_All:
      return true;
      break;
    case CBondContainer::BondSC_Country:
      bRet = IsBondCountry();
      break;
    case CBondContainer::BondSC_Center:
      bRet = IsBondCenter();
      break;
    case CBondContainer::BondSC_Finance:
      bRet = IsBondFinance();
      break;
    case CBondContainer::BondSC_Local:
      bRet = IsBondLocal();
      break;
    case CBondContainer::BondSC_Short:
      bRet = IsBondShort_S();
      break;
    case CBondContainer::BondSC_CShort:
      bRet = IsBondCShort();
      break;
    case CBondContainer::BondSC_China:
      bRet = IsBondChina();
      break;
    case CBondContainer::BondSC_Enterpr:
      bRet = IsBondEnterpr();
      break;
    case CBondContainer::BondSC_COP:
      bRet = IsBondCOP();
      break;
    case CBondContainer::BondSC_NCD:
      bRet = IsBondNCD();
      break;
    case CBondContainer::BondSC_PPN:
      bRet = IsBondPPN();
      break;
    case CBondContainer::BondSC_ABS:
      bRet = IsBondABS();
      break;
    case CBondContainer::BondSC_Other:
      if (IsBondShort_S() || IsBondCShort() || IsBondChina() ||
          IsBondEnterpr() || IsBondCOP() /*信用债*/
          || IsBondNCD()                 /*NCD*/
          || IsBondPPN() || IsBondABS()  /*私募债*/
          || IsBondCountry() || IsBondCenter() || IsBondFinance() ||
          IsBondLocal() /*利率债*/) {
        bRet = false;
      } else {
        bRet = true;
      }

      // bRet = IsBondOther();

      break;
    default:
      return false;
      break;
  }

  return bRet;
}

bool CBondInfoImpl::CheckHYBondType(const BLHCONDITION& Cond) const {
  for (int i = 0; i < BLH_BONDTYPECOUNT; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::BondSC_None) return false;
    if (CheckHYBondType(Cond.nTypeNew[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckHYBondType(uint32_t nSubType) const {
  bool bRet = false;
  switch (nSubType) {
    case CBondContainer::ProdNone:
      return false;
      break;
    case CBondContainer::ProdAll:
      return true;
      break;
    default:
      return false;
      break;
  }
  return bRet;
}

bool CBondInfoImpl::CheckComplexBondType(const BLHCONDITION& Cond) const {
  for (int i = 0; i < CBondContainer::BondC_Max; i++) {
    if (Cond.nTypeNew[i] == CBondContainer::BondC_None) return false;
    if (CheckComplexBondType(Cond.nTypeNew[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckComplexBondType(uint32_t nSubType) const {
  bool bRet = false;
  switch (nSubType) {
    case CBondContainer::BondC_None:
      return false;
      break;
    case CBondContainer::BondC_All:
      return true;
      break;
    case CBondContainer::BondC_Country:
      bRet = IsBondCountry();
      break;
    case CBondContainer::BondC_Center:
      bRet = IsBondCenter();
      break;
    case CBondContainer::BondC_Finance:
      bRet = IsBondFinance();
      break;
    case CBondContainer::BondC_Local:
      bRet = IsBondLocal();
      break;
    case CBondContainer::BondC_Short:
      bRet = IsBondShort_S();
      break;
    case CBondContainer::BondC_CShort:
      bRet = IsBondCShort();
      break;
    case CBondContainer::BondC_China:
      bRet = IsBondChina();
      break;
    case CBondContainer::BondC_Enterpr: {
      bRet = IsBondEnterpr();
      break;
    }
    case CBondContainer::BondC_COP: {
      bRet = IsBondCOP();
      break;
    }
    case CBondContainer::BondC_NonPublicCor: {
      bRet = IsBondNonPublicCor();
      break;
    } break;
    case CBondContainer::BondC_NCD:
      bRet = IsBondNCD();
      break;
    case CBondContainer::BondC_PPN:
      bRet = IsBondPPN();
      break;
    case CBondContainer::BondC_ABS:
      bRet = IsBondABS();
      break;
    case CBondContainer::BondC_Other: {
      if (IsBondPPN()) {
        bRet = false;
      } else
        bRet = IsBondOther();
    } break;
    default:
      return false;
      break;
  }
  return bRet;
}

bool CBondInfoImpl::CheckRightEx(const BLHCONDITION& Cond) const  // 含权类型
{
  if (Cond.nRightEx[0] == CBondContainer::RightExAll) return true;
  USE_FIELD(CBondInfoImpl, m_sOptionType, false);
  bool isRight = IsRight();
  bool ret = false;
  int sz = sizeof(Cond.nRightEx) / sizeof(uint32_t);
  for (int i = 0; i < sz; i++) {
    if (Cond.nRightEx[i] == CBondContainer::RightExNone) break;
    switch (Cond.nRightEx[i]) {
      case CBondContainer::RightExNo:
        ret |= (!isRight);
        break;
      case CBondContainer::RightExCal:
        ret |= (isRight && (strcmp(m_sOptionType, "CAL") == 0 ||
                            strcmp(m_sOptionType, "CNP") == 0));
        break;
      case CBondContainer::RightExPut:
        ret |= (isRight && (strcmp(m_sOptionType, "PUT") == 0 ||
                            strcmp(m_sOptionType, "CNP") == 0));
        break;
      case CBondContainer::RightExOther:
        ret |= (isRight && strcmp(m_sOptionType, "CAL") != 0 &&
                strcmp(m_sOptionType, "PUT") != 0 &&
                strcmp(m_sOptionType, "CNP") != 0);
        break;
      default:
        break;
    }
  }
  return ret;
}

bool CBondInfoImpl::CheckIssuer(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  if (Cond.szIssuer[0][0] == '\0') return true;
  for (int i = 0; i < BLH_ISSUERCOUNT; i++) {
    if (Cond.szIssuer[i][0] == '\0') return false;
    if (strcmp(m_sIssuerCode, Cond.szIssuer[i]) == 0) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckGuarantor(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sWarranter, false);
  if (Cond.szGuarantor[0][0] == '\0') return true;
  for (int i = 0; i < BLH_ISSUERCOUNT; i++) {
    if (Cond.szGuarantor[i][0] == '\0') return false;
    if (strstr(m_sWarranter, Cond.szGuarantor[i]) != 0) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckSector(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  if (Cond.szSector[0][0] == '\0') return true;

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;

  for (int i = 0; i < BLH_SECTORCOUNT; i++) {
    if (Cond.szSector[i][0] == '\0') return false;
    if (strcmp(Cond.szSector[i],
               pI->field((int)kIssuerInfo::SW_Subsector_Code)) == 0)
      return true;
  }

  return false;
}

bool CBondInfoImpl::CheckSector2021(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  if (Cond.szSector2021[0][0] == '\0') return true;

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;

  for (int i = 0; i < BLH_SECTORCOUNT; i++) {
    if (Cond.szSector2021[i][0] == '\0') return false;
    if (strcmp(Cond.szSector2021[i],
               pI->field((int)kIssuerInfo::SW_2021_Subsector_Code)) == 0)
      return true;
  }
  return false;
}

bool CBondInfoImpl::CheckSector2021(
    const std::vector<std::string>& vctSector2021) const  // 判断2021申万行业
{
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  if (vctSector2021.size() <= 0) return true;

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;

  const char* sSector = pI->field((int)kIssuerInfo::SW_2021_Subsector_Code);
  if (!sSector) return false;
  return std::find(vctSector2021.begin(), vctSector2021.end(), sSector) !=
         vctSector2021.end();
}

bool CBondInfoImpl::CheckArea(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  if (Cond.szArea[0][0] == '\0') return true;

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;

  for (int i = 0; i < BLH_SECTORCOUNT; i++) {
    if (Cond.szArea[i][0] == '\0') return false;
    if (strcmp(Cond.szArea[i], pI->field((int)kIssuerInfo::Province_Code)) == 0)
      return true;
  }

  return false;
}

bool CBondInfoImpl::CheckMuniArea(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  if (Cond.szMuniArea[0][0] == '\0') return true;

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;

  for (int i = 0; i < BLH_MUNIAREACOUNT; i++) {
    if (Cond.szMuniArea[i][0] == '\0') return false;
    if (strcmp(Cond.szMuniArea[i],
               pI->field((int)kIssuerInfo::Municipal_code)) == 0)
      return true;
  }
  return false;
}

bool CBondInfoImpl::CheckLocalBondArea(const BLHCONDITION& Cond) const {
  if (!IsBondLocal()) return false;
  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  for (int i = 0; i < BLH_LOCALBONDAREACOUNT; i++) {
    if (Cond.szLocalBondArea[i][0] == '\0') {
      if (i == 0) return true;  // all
      break;
    }
    if (strcmp(Cond.szLocalBondArea[i],
               pI->field((int)kIssuerInfo::Province_Code)) == 0)
      return true;
  }
  return false;
}

bool CBondInfoImpl::CheckMainUnderwriter(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sMainUnderwriters, false);
  if (Cond.szMainUnderwriter[0][0] == '\0') return true;
  for (int i = 0; i < 200; i++) {
    if (Cond.szMainUnderwriter[i][0] == '\0') return false;
    if (strstr(m_sMainUnderwriters, Cond.szMainUnderwriter[i]) != NULL)
      return true;
  }
  return false;
}

bool CBondInfoImpl::CheckBontSubType(const BLHCONDITION& Cond) const {
  if (Cond.szSubType[0][0] == '\0') return true;
  for (int i = 0; i < BLH_SUBTYPECOUNT; i++) {
    if (Cond.szSubType[i][0] == '\0') return false;
    if (CheckBontSubType(Cond.szSubType[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckBontSubType(const char* pSubType) const {
  if (!pSubType || IsEmpty(pSubType)) return false;

  if (strcmp(pSubType, "COP") == 0)  // 公司债
  {
    if (IsBondCorporate()) {
      return true;
    }

    return false;
  } else if (strcmp(pSubType, "DCO") == 0)  // 非公开公司债
  {
    if (IsBondNonPublicCor()) {
      return true;
    }

    return false;
  } else if (strcmp(pSubType, "PPN") == 0)  // PPN
  {
    if (IsBondPPN()) {
      return true;
    }
    return false;
  }

  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, pSubType) == 0) return true;
  return false;
}

bool CBondInfoImpl::CheckDebtRating(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sBondRating, false);
  if (Cond.nDebtRating[0] == CBondContainer::DRatingNone ||
      Cond.nDebtRating[0] == CBondContainer::DRatingAll)
    return true;

  const char* pBondRating = m_sBondRating;
  for (int i = 0; i < BLH_DEBTRATECOUNT; i++) {
    uint32_t flag = Cond.nDebtRating[i];
    if (flag == CBondContainer::DRatingNone) return false;
    if (flag == CBondContainer::DRatingAll) return true;
    switch (flag) {
      case CBondContainer::DRatingAAA:
        if (strcmp(pBondRating, "AAA") == 0) return true;
        break;
      case CBondContainer::DRatingA_1:
        if (strcmp(pBondRating, "A-1") == 0) return true;
        break;
      case CBondContainer::DRatingAAP:
        if (strcmp(pBondRating, "AA+") == 0) return true;
        break;
      case CBondContainer::DRatingAA:
        if (strcmp(pBondRating, "AA") == 0) return true;
        break;
      case CBondContainer::DRatingAAN:
        if (strcmp(pBondRating, "AA-") == 0) return true;
        break;
      case CBondContainer::DRatingAP:
        if (strcmp(pBondRating, "A+") == 0) return true;
        break;
      case CBondContainer::DRatingOther:
        if (IsEmpty(pBondRating)) return true;
        if (strcmp(pBondRating, "AAA") != 0 &&
            strcmp(pBondRating, "A-1") != 0 &&
            strcmp(pBondRating, "AA+") != 0 && strcmp(pBondRating, "AA") != 0 &&
            strcmp(pBondRating, "AA-") != 0 && strcmp(pBondRating, "A+") != 0)
          return true;
        break;
      default:
        return false;
        break;
    }
  }
  return false;
}

//  add  by  lbl    检查NCD 类型
bool CBondInfoImpl::CheckNCDRating(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sBondRating, false);
  if (Cond.nNCDRating[0] == CBondContainer::NCDRatingNone ||
      Cond.nNCDRating[0] == CBondContainer::NCDRatingAll)
    return true;

  if (!IsBondNCD()) return false;
  const char* pNCDRating = GetIssuerRating();  // NCD  主体评级
  const char* NCDtype = GetBondSubType();      //  类型
  if (!NCDtype) return false;

  for (int i = 0; i < BLH_DEBTRATECOUNT; i++) {
    uint32_t flag = Cond.nNCDRating[i];
    if (flag == CBondContainer::NCDRatingNone) return false;
    if (flag == CBondContainer::NCDRatingAll) return true;
    switch (flag) {
      case CBondContainer::NCDRatingSHDMCD:  //  国有/ 股份制
        if (strcmp(NCDtype, "SHD") == 0 || strcmp(NCDtype, "MCD") == 0)
          return true;
        break;
      case CBondContainer::NCDRatingAAA:  //	AAA
        if ((strcmp(NCDtype, "SHD") != 0 && strcmp(NCDtype, "MCD") != 0) &&
            pNCDRating && strcmp(pNCDRating, "AAA") == 0)
          return true;
        break;
      case CBondContainer::NCDRatingAAP:  //	AA+
        if ((strcmp(NCDtype, "SHD") != 0 && strcmp(NCDtype, "MCD") != 0) &&
            pNCDRating && strcmp(pNCDRating, "AA+") == 0)
          return true;
        break;
      case CBondContainer::NCDRatingAA:  //	AA
        if ((strcmp(NCDtype, "SHD") != 0 && strcmp(NCDtype, "MCD") != 0) &&
            pNCDRating && strcmp(pNCDRating, "AA") == 0)
          return true;
        break;
      case CBondContainer::NCDRatingAA2:  //  AA- 及以下
        if ((strcmp(NCDtype, "SHD") != 0 && strcmp(NCDtype, "MCD") != 0) &&
            (!pNCDRating ||
             (strcmp(pNCDRating, "AAA") != 0 &&
              strcmp(pNCDRating, "AA+") != 0 && strcmp(pNCDRating, "AA") != 0)))
          return true;
        break;
      default:
        return false;
        break;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckFinDebt(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  bool needCheck = false;
  if (!needCheck) {
    for (int i = 0; i < BLH_FINDEBTCOUNT; i++) {
      if (Cond.nFinDebt[i] == CBondContainer::FinDebtAll) return true;
    }
    return false;
  }

  // if(!CheckBondType(CBondContainer::BondFinance))return true;
  const char* issuerCode = m_sIssuerCode;
  for (int i = 0; i < BLH_FINDEBTCOUNT; i++) {
    switch (Cond.nFinDebt[i]) {
      case CBondContainer::FinDebtAll:
        return true;
        break;
      case CBondContainer::FinDebtCDB:  // 国开
        if (strcmp(m_sBondSubType, "PSB") != 0 &&
            strcmp(issuerCode, "G000124") == 0)
          return true;
        break;
      case CBondContainer::FinDebtInAndEx:  // 进出口
        if (strcmp(m_sBondSubType, "PSB") != 0 &&
            strcmp(issuerCode, "Z000189") == 0)
          return true;
        break;
      case CBondContainer::FinDebtAgDp:  // 农发
        if (strcmp(m_sBondSubType, "PSB") != 0 &&
            strcmp(issuerCode, "Z000207") == 0)
          return true;
        break;
      case CBondContainer::FinDebtNone:
      default:
        return false;
        break;
    }
  }
  return false;
}

bool CBondInfoImpl::CheckIssueYear(const BLHCONDITION& Cond) const {
  // 性能优化:避免m_sIssueStartDate被反复读取;
  // 性能优化:避免nYear被反复计算;
  // 警告:整数整除/10000
  // 功能:检查当前债券的起始发行日期的年份是否与给定条件的年份中的某一个相同
  const char* issue_start_date = GetIssueStartDate();
  bool calculated = false;
  int nYear = 0;
  for (int i = 0; i < BLH_ISSUEYEARCOUNT; i++) {
    if (Cond.nIssueYear[i] == 0) {
      if (i == 0)
        return true;
      else
        return false;
    }
    if (!calculated) {
      if (IsEmpty(issue_start_date)) return false;
      nYear = atoi(issue_start_date) / 10000;
      calculated = true;
    }
    if (nYear == Cond.nIssueYear[i]) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckIssueYear(int nYear) const {
  const char* issue_start_date = GetIssueStartDate();
  if (IsEmpty(issue_start_date)) return false;
  int nIssueYear = atoi(issue_start_date) / 10000;
  return nYear == nIssueYear;
}

bool CBondInfoImpl::CheckIssueYear(int nBegin, int nEnd) const {
  const char* issue_start_date = GetIssueStartDate();
  if (IsEmpty(issue_start_date)) return false;
  int nIssueYear = atoi(issue_start_date) / 10000;
  if (nBegin > 0 && nEnd > 0) {
    return nIssueYear >= nBegin && nIssueYear <= nEnd;
  } else if (nBegin > 0) {
    return nIssueYear >= nBegin;
  } else if (nEnd > 0) {
    return nIssueYear <= nEnd;
  }
  return false;
}

bool CBondInfoImpl::CheckUnderwriter(const BLHCONDITION& Cond) const {
  if ('\0' == Cond.szUnderwriter[0] ||
      NULL != strstr(m_sUnderwrites, Cond.szUnderwriter))
    return true;
  return false;
}

void CBondInfoImpl::SetValidity(bool valid) {
  USE_FIELD(CBondInfoImpl, m_flag, true);
  m_flag.SetValidFlag(valid);
}

bool CBondInfoImpl::IsValidBond() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetValidFlag();
}

bool CBondInfoImpl::IsTransBond() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return IsCVBBond()                             // 不可分离可转债
         || strcmp(m_sBondSubType, "SCV") == 0;  // 可分离可转债
}

bool CBondInfoImpl::IsCVBBond() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return strcmp(m_sBondSubType, "CVB") == 0;  // 不可分离可转债
}

bool CBondInfoImpl::IsBondBankSecond() const  // 银行二级债
{
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return (strcmp(m_sBondSubType, "TET") == 0 && !IsETSBond() &&
          IsBondSWFirstBank());
}

bool CBondInfoImpl::IsBondBankPerpetual() const  // 银行永续债
{
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return (strcmp(m_sBondSubType, "TET") == 0 && IsETSBond() &&
          IsBondSWFirstBank());
}

bool CBondInfoImpl::IsPolicyBankSecond() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return strcmp(m_sBondSubType, "PSB") == 0;
}

bool CBondInfoImpl::IsBondCommercialBank() const  // 商业银行债
{
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return strcmp(m_sBondSubType, "CBB") == 0 || IsBondTLAC();
}

bool CBondInfoImpl::IsBondSceniority() const {
  USE_FIELD(CBondInfoImpl, m_Sceniority, false);
  return strcmp(m_Sceniority, "SUB") == 0;
}

bool CBondInfoImpl::IsBondSWFirstBank() const {
  static std::vector<std::string> vSector = {"031801", "031802", "031803",
                                             "031804", "031805"};
  return CheckSector2021(vSector);
}

bool CBondInfoImpl::IsBondSubordinate() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return strcmp(m_sBondSubType, "PSB") == 0      // 政策性银行次级债
         || strcmp(m_sBondSubType, "CSB") == 0   // 商业银行次级债
         || strcmp(m_sBondSubType, "SES") == 0   // 证券公司次级债
         || strcmp(m_sBondSubType, "TET") == 0;  // 二级资本工具
}

bool CBondInfoImpl::IsBondTLAC() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return strcmp(m_sBondSubType, "TLC") == 0;
}

bool CBondInfoImpl::is_credit_bond() const {
  bool bRet = false;
  if (!is_interest_bond() && !IsBondNCD()) bRet = true;

  return bRet;
}

bool CBondInfoImpl::is_industry_bond() const  // 含金融机构债，需要二次手工剔除
{
  return (!IsMunicipal() && is_credit_bond());  // 属于信用债并且非城投债
}

bool CBondInfoImpl::is_interest_bond() const {
  bool bRet = false;

  if (CheckBondTypeNew(CBondContainer::newBondCountry) ||
      CheckBondTypeNew(CBondContainer::newBondCenter) ||
      CheckBondTypeNew(CBondContainer::newBondFinance) ||
      CheckBondTypeNew(CBondContainer::newBondLocal))
    bRet = true;

  return bRet;
}

bool CBondInfoImpl::IsBondFinancialInstitutions() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  static std::vector<std::string> tgtType = {"PSB", "CBB", "CSB", "CXB",
                                             "NCB", "SFB", "SEB", "SSB",
                                             "SES", "HJB", "TET", "TLC"};
  const char* subType = m_sBondSubType;
  return std::find(tgtType.begin(), tgtType.end(), subType) != tgtType.end();
  // 	for (auto subType : tgtType)
  // 	{
  // 		if (strcmp(m_sBondSubType, subType.c_str()) == 0)
  // 		{
  // 			return true;
  // 		}
  // 	}
  // 	return false;
}

bool CBondInfoImpl::IsCreditBond(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  // 只分利率债和信用债
  if (strcmp(GetListedMarket(), CBondContainer::lmCIB) != 0) return false;

  if (Cond.nCreditBond == CBondContainer::BondLC_Credit ||
      Cond.nCreditBond == CBondContainer::BondLC_InterestRate) {
    bool bCredit = false;
    if (CheckBondTypeNew(CBondContainer::newBondCountry) ||
        CheckBondTypeNew(CBondContainer::newBondCenter) ||
        CheckBondTypeNew(CBondContainer::newBondFinance) ||
        CheckBondTypeNew(CBondContainer::newBondLocal) ||
        CheckBondTypeNew(CBondContainer::newBondNCD))
      bCredit = false;
    else
      bCredit = true;

    if (Cond.nCreditBond == CBondContainer::BondLC_Credit && bCredit)
      return true;
    if (Cond.nCreditBond == CBondContainer::BondLC_InterestRate && !bCredit)
      return true;
  } else if (Cond.nCreditBond == CBondContainer::BondLC_PPN)  // PPN
  {
    if (strcmp(m_sBondSubType, "PPN") == 0) return true;
  }

  return false;
}

bool CBondInfoImpl::IsInDays(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssueStartDate, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sIssueEndDate, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sAnnounceDate, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sPaymentDate, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sListDate, false);
  if (Cond.nIssueStartDate[0] > 0 && Cond.nIssueStartDate[1] > 0) {
    int nStart = atoi(m_sIssueStartDate);
    int nEnd = atoi(m_sIssueEndDate);
    if (nStart <= 0) return false;
    if (nEnd <= 0 || nStart > nEnd) nEnd = nStart;
    if (nEnd < Cond.nIssueStartDate[0] || nStart > Cond.nIssueStartDate[1])
      return false;
  }

  if (Cond.nAnnounceDate[0] > 0 && Cond.nAnnounceDate[1] > 0) {
    int nDate = atoi(m_sAnnounceDate);
    if (nDate <= 0 || nDate < Cond.nAnnounceDate[0] ||
        nDate > Cond.nAnnounceDate[1])
      return false;
  }

  if (Cond.nPaymentDate[0] > 0 && Cond.nPaymentDate[1] > 0) {
    int nDate = atoi(m_sPaymentDate);
    if (nDate <= 0 || nDate < Cond.nPaymentDate[0] ||
        nDate > Cond.nPaymentDate[1])
      return false;
  }

  if (Cond.nListedDate[0] > 0 && Cond.nListedDate[1] > 0) {
    int nDate = atoi(m_sListDate);
    if (nDate <= 0 || nDate < Cond.nListedDate[0] ||
        nDate > Cond.nListedDate[1])
      return false;
  }

  if (Cond.nInterestStartDate[0] > 0 && Cond.nInterestStartDate[1] > 0) {
    int nDate = atoi(GetInterestStartDate());
    if (nDate <= 0 || nDate < Cond.nInterestStartDate[0] ||
        nDate > Cond.nInterestStartDate[1])
      return false;
  }

  return true;
  ;
}

bool CBondInfoImpl::CheckIssueState(BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_sIssuePeriod, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sCouponRateCurrent, false);
  switch (Cond.nIssueState) {
    case CBondContainer::BondIssueState_None:
      return true;
      break;
    case CBondContainer::BondIssueState_Issuing: {
      if (!IsEmpty(m_sIssuePeriod))
        return false;
      else if (!IsEmpty(m_sCouponRateCurrent))  // m_fCouponRateCurrent>0.0000)
        return false;
      else
        return true;
    } break;
    case CBondContainer::BondIssueState_Issued: {
      // 贴现债，票面利率可能是0，但是是已发行，而为NULL的则是预发行
      if (!IsEmpty(m_sCouponRateCurrent))  // m_fCouponRateCurrent>0.0000)
        return true;
      else
        return false;
    } break;
    case CBondContainer::BondIssueState_PreIssue: {
      if (!IsEmpty(m_sIssuePeriod))
        return true;
      else
        return false;
    } break;
    default:
      return false;
      break;
  }
  return true;
}

bool CBondInfoImpl::CheckAssetStatus(const BLHCONDITION& Cond) const {
  for (int i = 0; i < _countof(Cond.nAssetStatus); i++) {
    if (Cond.nAssetStatus[i] == CBondContainer::AssetNone) return false;
    if (CheckAssetStatus(Cond.nAssetStatus[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckAssetStatus(uint32_t nStatus) const {
  USE_FIELD(CBondInfoImpl, m_sAssetStatus, false);
  switch (nStatus) {
    case CBondContainer::AssetAll:  // 全部
      return true;
      break;
    case CBondContainer::AssetPri:
      if (qstricmp(m_sAssetStatus, "PRI") == 0)  // 私募
        return true;
      break;
    case CBondContainer::AssetPub:
      if (qstricmp(m_sAssetStatus, "PUB") == 0)  // 小公募
        return true;
      break;
    case CBondContainer::AssetNull:      // 信用债公募
      if (IsRatingDebt()) return false;  // 利率债
      if (qstricmp(m_sAssetStatus, "PRI") != 0 &&
          qstricmp(m_sAssetStatus, "PUB") != 0)
        return true;
      break;
    case CBondContainer::
        AssetNonPri:  // 非私募，用于上证固收平台，包括信用债和利率债
      if (IsRatingDebt()) return true;  // 利率债
      if (qstricmp(m_sAssetStatus, "PRI") != 0) return true;
      break;
    default:
      break;
  }
  return false;
}

bool CBondInfoImpl::CheckABSCoupon(const BLHCONDITION& Cond) const {
  for (int i = 0; i < 20; i++) {
    int nCouponType = Cond.nABSCoupon[i];
    if (nCouponType == CABSBondInfo::COUPON_ALL) return false;
    if (CheckABSCoupon(nCouponType)) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckABSCoupon(int nCouponType) const {
  USE_FIELD(CBondInfoImpl, m_sCouponType, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sFRNIndexID, false);
  USE_FIELD_ADD(CBondInfoImpl, m_NextCoupon_Date, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sMaturityDate, false);
  switch (nCouponType) {
    case CABSBondInfo::COUPON_ALL:  // 全部
      return true;
      break;
    case CABSBondInfo::COUPON_FIXED:  // 固息
      // 筛选显示固息债券报价和成交，Coupon_Type =
      // ZRO，DSC，FRB，PAM。或：Coupon_Type = FRN, 且Next_Coupon_Date =
      // Maturity_Date。
      if ((strcmp(m_sCouponType, "ZRO") == 0 ||
           strcmp(m_sCouponType, "DSC") == 0 ||
           strcmp(m_sCouponType, "FRB") == 0 ||
           strcmp(m_sCouponType, "PAM") == 0) ||
          (strcmp(m_sCouponType, "FRN") == 0 &&
           strcmp(m_NextCoupon_Date, m_sMaturityDate) == 0)) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_DEPO_1Y:  // DEPO_1Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含DEPO_1Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "DEPO_1Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_LRB_1Y:  // LRB_1Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含LRB_1Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "LRB_1Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_LRB_5Y:  // LRB_5Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含LRB_5Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "LRB_5Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_LRB_1Y_3Y:  // LRB_1Y_3Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含LRB_1Y_3Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "LRB_1Y_3Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_LRB_1Y_5Y:  // LRB_1Y_5Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含LRB_1Y_5Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "LRB_1Y_5Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_LPR_1Y:  // LPR_1Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含LPR_1Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "LPR_1Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_LPR_5Y:  // LPR_5Y
      // 筛选显示SHIBOR报价和成交，Coupon_Type=FRN,且FRN_Index_ID字段包含LPR_5Y，并且Next_Coupon_Date≠Maturity_Date
      if (strcmp(m_sCouponType, "FRN") == 0 &&
          strcmp(m_sFRNIndexID, "LPR_5Y") == 0 &&
          strcmp(m_NextCoupon_Date, m_sMaturityDate) != 0) {
        return true;
      } else
        return false;
      break;
    case CABSBondInfo::COUPON_OTHER:  // 其他
      for (int nType = CABSBondInfo::COUPON_FIXED;
           nType < CABSBondInfo::COUPON_OTHER; nType++) {
        if (CheckABSCoupon(nType)) return false;
      }
      return true;
      break;
    default:
      break;
  }
  return false;
}

bool CBondInfoImpl::CheckCouponRate(const BLHCONDITION& Cond) const  // 票面利率
{
  if (Cond.sCouponRate[0] == '\0' && Cond.sCouponRateEnd[0] == '\0')
    return true;
  const char* pRate = GetCouponRateCurrent();

  if (!IsNumber(pRate)) return false;
  double rate = atof(pRate);

  if (Cond.sCouponRate[0] != '\0') {
    double rate0 = atof(Cond.sCouponRate);
    if (rate < rate0 - 1e-6) return false;
  }
  if (Cond.sCouponRateEnd[0] != '\0') {
    double rate1 = atof(Cond.sCouponRateEnd);
    if (rate > rate1 + 1e-6) return false;
  }
  return true;
}

bool CBondInfoImpl::CheckCategoryFlag(const BLHCONDITION& Cond) const {
  USE_FIELD(CBondInfoImpl, m_CategoryFlag, false);
  if (Cond.szCategoryFlag[0][0] == '\0') return true;

  for (int i = 0; i < BLH_ISSUEYEARCOUNT; i++) {
    if (Cond.szCategoryFlag[i][0] == '\0') return false;
    if (strcmp(m_CategoryFlag, Cond.szCategoryFlag[i]) == 0) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckBankBondType(const BLHCONDITION& Cond) const {
  static std::vector<std::string> vSector = {
      "0", "0", "031801", "031802", "031803", "031804", "031805"};
  if (Cond.nBankBond[0] == CBondContainer::BankAll) return true;

  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;
  const char* sSector = pI->field((int)kIssuerInfo::SW_2021_Subsector_Code);
  int count = _countof(Cond.nBankBond);
  for (auto type : Cond.nBankBond) {
    if (type == CBondContainer::BankNone) return false;
    if (strcmp(sSector, vSector[type].c_str()) == 0) return true;
  }
  return false;
}

void CBondInfoImpl::SetBondSubType(const char* szBondSubType) {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, true);
  m_sBondSubType = szBondSubType;
}

void CBondInfoImpl::SetRemainDate(const char* sRemainDate) {
  USE_FIELD(CBondInfoImpl, m_sRemainDate, true);
  USE_FIELD_ADD(CBondInfoImpl, m_sRemainDateDisplay, true);
  if (sRemainDate == NULL) {
    return;
  }
  m_sRemainDate = sRemainDate;
  m_sRemainDateDisplay = sRemainDate;
}

const char* CBondInfoImpl::GetArea(bool eng) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);

  if (pI != NULL && !IsEmpty(pI->field((int)kIssuerInfo::Province_Code))) {
    const QBPROVINCEINFO* pArea = CQBProvinceInfo::instance().GetProviceInfo(
        pI->field((int)kIssuerInfo::Province_Code));
    if (pArea != NULL) {
      if (eng) return pArea->Area_English_Name;
      return pArea->Area_Name;
    }
  }

  return "";  // 不返回NULL，是为了更好的适应外部接口，例如strcmp函数
}

const char* CBondInfoImpl::GetSwSector(bool eng) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);

  if (pI != NULL &&
      !IsEmpty(pI->field((int)kIssuerInfo::SW_2021_Sector_Code))) {
    const QBSWSECTORINFO* pSector =
        CQBSwSectorInfo::instance2021().GetSwSectorInfo(
            std::string(pI->field((int)kIssuerInfo::SW_2021_Sector_Code)));
    if (pSector != NULL) {
      if (eng) return pSector->SW_English_Name;
      return pSector->SW_Name;
    }
  }
  return "";
}

const char* CBondInfoImpl::GetSwSubSector(bool eng) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);

  if (pI != NULL &&
      !IsEmpty(pI->field((int)kIssuerInfo::SW_2021_Subsector_Code))) {
    const QBSWSECTORINFO* pSector =
        CQBSwSectorInfo::instance2021().GetSwSectorInfo(
            std::string(pI->field((int)kIssuerInfo::SW_2021_Subsector_Code)));
    if (pSector != NULL) {
      if (eng) return pSector->SW_English_Name;
      return pSector->SW_Name;
    }
  }

  return "";
}

bool CBondInfoImpl::IsSuperNewBond(const BLHCONDITION& Cond) const {
  // 2015/08/12 bushion,abs和ppN合并为私募债
  if (Cond.nCreditBond == CBondContainer::BondLC_PrivateDebet) {  // PPN,ABS
    if (IsBondPPN())
      return true;
    else if (IsBondABS())
      return true;
  } else if (Cond.nCreditBond == CBondContainer::BondLC_NCD)  // NCD
  {
    if (IsBondNCD()) return true;
  } else {
    if (IsBondPPN() || IsBondABS() || IsBondNCD()) return false;

    if (Cond.nCreditBond == CBondContainer::BondLC_Credit ||
        Cond.nCreditBond == CBondContainer::BondLC_InterestRate) {
      bool bCredit = false;
      if (IsBondCountry() || IsBondCenter() || IsBondFinance() || IsBondLocal())
        bCredit = false;
      else
        bCredit = true;

      if (Cond.nCreditBond == CBondContainer::BondLC_Credit &&
          bCredit)  // 信用债
      {
        return true;
      }

      if (Cond.nCreditBond == CBondContainer::BondLC_InterestRate &&
          !bCredit)  // 利率债
      {
        return true;
      }
    }
  }
  return false;
}

const char* CBondInfoImpl::GetInstitutionShortName(bool eng) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (pI != NULL) {
    if (eng) return pI->field((int)kIssuerInfo::Short_Name_E);
    return pI->field((int)kIssuerInfo::Short_Name_C);
  }
  return "";
}

const char* CBondInfoImpl::GetInstitutionFullName(bool eng) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (pI != NULL) {
    if (eng) return pI->field((int)kIssuerInfo::Full_Name_E);
    return pI->field((int)kIssuerInfo::Full_Name_C);
  }
  return "";
}

const char* CBondInfoImpl::GetCouponTypeName(bool eng) const {
  static BondDict dictBondType;
  memset(&dictBondType, 0, sizeof(dictBondType));
  CBondDict::instance().GetBondDict("Coupon_Type", GetCouponType(),
                                    dictBondType);
  if (eng) return dictBondType.selective_content_en;
  return dictBondType.selective_content;

  return "";
}

const char* CBondInfoImpl::GetOptionTypeName(bool eng) const {
  static BondDict dictBondType;
  CBondDict::instance().GetBondDict("Option_Type", GetOptionType(),
                                    dictBondType);
  if (eng) return dictBondType.selective_content_en;
  return dictBondType.selective_content;
  return "";
}

void CBondInfoImpl::SetOutlook(const char* sOutlook) {
  USE_FIELD(CBondInfoImpl, m_sOutlook, true);
  USE_FIELD(CBondInfoImpl, m_nOutlookLevel, true);
  m_sOutlook = sOutlook;

  if (!sOutlook || sOutlook[0] == 0x0) m_nOutlookLevel = -1;
  if (strcmp(sOutlook, "NON") == 0)
    m_nOutlookLevel = 1;  // 无
  else if (strcmp(sOutlook, "NEG") == 0)
    m_nOutlookLevel = 2;  // 负面
  else if (strcmp(sOutlook, "RWT") == 0)
    m_nOutlookLevel = 3;  // 列入观察
  else if (strcmp(sOutlook, "STB") == 0)
    m_nOutlookLevel = 4;  // 稳定
  else if (strcmp(sOutlook, "POS") == 0)
    m_nOutlookLevel = 5;  // 正面
  else
    m_nOutlookLevel = 0;  // 不明确
}

void CBondInfoImpl::SetEntCor(const char* sEntCor) {
  USE_FIELD(CBondInfoImpl, m_sEntCor, true);
  m_sEntCor = sEntCor;
}

void CBondInfoImpl::SetBondFileNum(int nBondFileNum) {
  USE_FIELD(CBondInfoImpl, m_nBondFileNum, true);
  m_nBondFileNum = nBondFileNum;
}

void CBondInfoImpl::SetAdditionInfoIndex(int nIndex) {
  USE_FIELD(CBondInfoImpl, m_nAdditionInfoIndex, true);
  m_nAdditionInfoIndex = nIndex;
}

void CBondInfoImpl::SetOptionInfoIndex(int nIndex) {
  USE_FIELD(CBondInfoImpl, m_nOptionInfoIndex, true);
  m_nOptionInfoIndex = nIndex;
}

const char* CBondInfoImpl::GetOutlookName(bool eng) const {
  static BondDict dictBondType;
  memset(&dictBondType, 0, sizeof(dictBondType));
  CBondDict::instance().GetBondDict("Outlook", GetOutlook(), dictBondType);
  if (eng) return dictBondType.selective_content_en;
  return dictBondType.selective_content;
}

const char* CBondInfoImpl::GetOutlook() const {
  USE_FIELD(CBondInfoImpl, m_sOutlook, false);
  return m_sOutlook;
}

int CBondInfoImpl::GetOutlookLevel() const {
  USE_FIELD(CBondInfoImpl, m_nOutlookLevel, false);
  return m_nOutlookLevel;
}

const char* CBondInfoImpl::GetEntCor() const {
  USE_FIELD(CBondInfoImpl, m_sEntCor, false);
  return m_sEntCor;
}

int CBondInfoImpl::GetBondFileNum() const {
  USE_FIELD(CBondInfoImpl, m_nBondFileNum, false);
  return m_nBondFileNum;
}

int CBondInfoImpl::GetOptionInfoIndex() const {
  USE_FIELD(CBondInfoImpl, m_nOptionInfoIndex, false);
  return m_nOptionInfoIndex;
}

const char* CBondInfoImpl::GetIssueRate() const {
  USE_FIELD(CBondInfoImpl, m_IssueRate, false);
  return m_IssueRate;
}

const char* CBondInfoImpl::GetPlannedExerciseDate() const {
  USE_FIELD(CBondInfoImpl, m_PlannedExerciseDate, false);
  return m_PlannedExerciseDate;
}

const char* CBondInfoImpl::GetNextCoupon_Date() const {
  USE_FIELD(CBondInfoImpl, m_NextCoupon_Date, false);
  return m_NextCoupon_Date;
}

const char* CBondInfoImpl::GetConversionRate() const {
  USE_FIELD(CBondInfoImpl, m_ConversionRate, false);
  return m_ConversionRate;
}

const char* CBondInfoImpl::GetAssetStatus() const {
  USE_FIELD(CBondInfoImpl, m_sAssetStatus, false);
  return m_sAssetStatus;
}

const char* CBondInfoImpl::GetPrincipalPayType() const {
  USE_FIELD(CBondInfoImpl, m_sPrincipayPayType, false);
  return m_sPrincipayPayType;
}

bool CBondInfoImpl::IsAmortizing() const {
  const char* type = GetPrincipalPayType();
  return (type != nullptr && strstr(type, "1") != nullptr);
}

bool CBondInfoImpl::IsNonAmortizing() const {
  const char* type = GetPrincipalPayType();
  return (type != nullptr && strstr(type, "2") != nullptr);
}

const CAdditionBondInfo* CBondInfoImpl::GetAdditionInfo() const {
  USE_FIELD(CBondInfoImpl, m_nAdditionInfoIndex, false);
  return CBondContainer::instance().GetAdditionBondInfo(m_nAdditionInfoIndex);
}

int CBondInfoImpl::GetCdcAuth() const {
  USE_FIELD(CBondInfoImpl, m_nCdcAuth, false);
  return m_nCdcAuth;
}

bool CBondInfoImpl::IsExpireInHoliday() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetExpireInHoliday();
}

bool CBondInfoImpl::IsAddIssueBond() const {
  USE_FIELD(CBondInfoImpl, m_nAdditionInfoIndex, false);
  return m_nAdditionInfoIndex >= 0;
}

bool CBondInfoImpl::IsFilterOutAddIssueBond() const {
  USE_FIELD(CBondInfoImpl, m_sMarketType, false);
  bool bRet = false;
  if (IsAddIssueBond() && atoi(m_sMarketType) != 1) {
    bRet = true;
  }
  return bRet;
}

bool CBondInfoImpl::IsBondCountry() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "BGB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "SGB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "EGB") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondCenter() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "SCB") == 0) return true;
  return false;
}
bool CBondInfoImpl::IsBondFinance() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PBB") == 0) return true;
  return false;
}
bool CBondInfoImpl::IsBondLocal() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  const char* subType = m_sBondSubType;
  if (strcmp(subType, "TLB") == 0)
    return true;
  else if (strcmp(subType, "LLB") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondShort() const  // 短融中包括超短融
{
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "LCP") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "SSB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CCP") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CSP") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "LSP") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondShort_S() const  // 短融中去掉超短融
{
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "LCP") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "SSB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CCP") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondCShort() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "CSP") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "LSP") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondMTN() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "LMN") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CMN") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondChina() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "LMN") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CMN") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondEnterpr() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "CCB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "COB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "RAB") == 0)
    return true;
  else {
    if (strcmp(m_sBondSubType, "CEB") == 0 ||
        strcmp(m_sBondSubType, "LEB") == 0) {
      if (strcmp(m_sEntCor, "ENT") == 0) return true;
    }
  };

  return false;

  // 	//2015/07/10 by
  // devin.zhang:应Vixen要求，将BondOther中的CCB、CVB、SCV调整为企业债；同时要满足：m_sEntCor
  // 不等于 "COP" 	if (strcmp(m_sBondSubType, "CCB")==0
  // ||strcmp(m_sBondSubType, "CEB")==0 ||strcmp(m_sBondSubType, "LEB")==0 ||
  // strcmp(m_sBondSubType, "RAB")==0 ||strcmp(m_sBondSubType, "CVB")==0
  // ||strcmp(m_sBondSubType, "SCV")==0)
  // 	{
  // 		if(strcmp(m_sEntCor, "COP")!=0)//2015/07/10 by devin.zhang:
  // 			return true;
  // 	}
  // 	return false;
}

bool CBondInfoImpl::IsBondCorporate() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "CEB") == 0 ||
      strcmp(m_sBondSubType, "LEB") == 0) {
    if (strcmp(m_sEntCor, "COP") == 0) return true;
  }

  return false;
}

bool CBondInfoImpl::IsBondNonPublicCor() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sEntCor, false);
  if (strcmp(m_sBondSubType, "PPN") == 0 && strcmp(m_sEntCor, "COP") == 0)
    return true;

  return false;
}

bool CBondInfoImpl::IsBondPPN() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PPN") == 0 && IsEmpty(m_sEntCor)) return true;
  return false;
}

bool CBondInfoImpl::IsBondCOP() const {
  if (IsBondCorporate() || IsBondNonPublicCor()) {
    return true;
  }

  return false;
}

bool CBondInfoImpl::IsBondCOPV2() const {
  if (IsBondCorporateV2() || IsBondNonPublicCor()) {
    return true;
  }

  return false;
}

bool CBondInfoImpl::IsBondCorporateV2() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);

  if (strcmp(m_sBondSubType, "CEB") == 0 ||
      strcmp(m_sBondSubType, "LEB") == 0) {
    if (strcmp(m_sEntCor, "COP") == 0) return true;
  }
  return false;
}

bool CBondInfoImpl::IsBondNCD() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (IsEmpty(m_sBondSubType)) return false;  // 快速返回
  if (strcmp(m_sBondSubType, "MCD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "SPD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "SHD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CCD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "RRD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "RTD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "FRD") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "OTD") == 0)
    return true;
  return false;
}
bool CBondInfoImpl::IsBondOther() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (IsEmpty(m_sBondSubType)) return false;  // 快速返回
  if (strcmp(m_sBondSubType, "COB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CBB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "NCB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "PPN") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "CSB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "SEB") == 0)
    return true;
  // else if(strcmp(m_sBondSubType, "CVB")==0)return true;//2015/07/10 by
  // devin.zhang:移到BondEnterpr和BondCOP else if(strcmp(m_sBondSubType,
  // "SCV")==0)return true;//2015/07/10 by devin.zhang:移到BondEnterpr和BondCOP
  else if (strcmp(m_sBondSubType, "HJB") == 0)
    return true;
  // else if(strcmp(m_sBondSubType, "CCB")==0)return true;//2015/07/10 by
  // devin.zhang:移到BondEnterpr和BondCOP
  else if (strcmp(m_sBondSubType, "CXB") == 0)
    return true;
  else if (strcmp(m_sBondSubType, "INT") == 0)
    return true;
  // else if(strcmp(m_sBondSubType, "MBS")==0)return true;//2015/12/24 by
  // bushion.xin:移到ABS else if(strcmp(m_sBondSubType, "LBS")==0)return
  // true;//2015/12/24 by bushion.xin:移到ABS else if(strcmp(m_sBondSubType,
  // "CBS")==0)return true;//2015/12/24 by bushion.xin:移到ABS else
  // if(strcmp(m_sBondSubType, "AMP")==0)return true;//2015/12/24 by
  // bushion.xin:移到ABS else if(strcmp(m_sBondSubType, "PDB")==0)return true;
  // //20160115  by Tony 移到金融债下 JIRA6618
  else if (strcmp(m_sBondSubType, "SES") == 0)
    return true;

  return false;
}

bool CBondInfoImpl::IsPrivateDebet() const {
  bool bRet = false;
  if (!bRet && IsBondPPN()) bRet = true;
  if (!bRet && IsBondABS()) bRet = true;
  return bRet;
}

bool CBondInfoImpl::IsPrivateCorpBond() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sEntCor, false);
  if (strcmp(m_sBondSubType, "PPN") == 0 && strcmp(m_sEntCor, "COP") == 0)
    return true;

  return false;
}

bool CBondInfoImpl::IsPubliceCorpBond() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "SCV") == 0 ||
      strcmp(m_sBondSubType, "CVB") == 0) {
    return true;
  } else if (strcmp(m_sBondSubType, "CEB") == 0 ||
             strcmp(m_sBondSubType, "LEB") == 0) {
    if (strcmp(m_sEntCor, "COP") == 0) {
      return true;
    }
  }

  return false;
}

bool CBondInfoImpl::IsETSBond() const {
  USE_FIELD(CBondInfoImpl, m_sOptionType, false);
  if (strcmp(m_sOptionType, "ETS") == 0) return true;

  return false;
}

bool CBondInfoImpl::IsBondABS() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "AMP") == 0 ||
      strcmp(m_sBondSubType, "CBS") == 0 ||
      strcmp(m_sBondSubType, "LBS") == 0 || strcmp(m_sBondSubType, "MBS") == 0)
    return true;  // ABS
  return false;
}

bool CBondInfoImpl::IsBondCRM() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "CRM") == 0 || strcmp(m_sBondSubType, "CLN") == 0)
    return true;  // CRM
  return false;
}

bool CBondInfoImpl::IsBondGKZ() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PSB") != 0 &&
      strcmp(m_sIssuerCode, "G000124") == 0)
    return true;
  return false;
}

bool CBondInfoImpl::IsBondInAndEx() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PBB") == 0 &&
      strcmp(m_sIssuerCode, "Z000189") == 0)
    return true;
  return false;
}

bool CBondInfoImpl::IsBondAgDev() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PBB") == 0 &&
      strcmp(m_sIssuerCode, "Z000207") == 0)
    return true;
  return false;
}

bool CBondInfoImpl::IsBondPDB() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "PDB") == 0) return true;
  return false;
}

bool CBondInfoImpl::IsBondSecondCapital() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "TET") == 0) return true;
  return false;
}

const char* CBondInfoImpl::GetIssuerBondRating() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerRating, false);
  USE_FIELD_ADD(CBondInfoImpl, m_sBondRating, false);
  // 假设债券主体评级与债项评级相同时，仅显示相同的评级，不相同时显示“主体/债项”
  // 主体评级与债项评级为"CCL"时，显示“--”
  static std::string sTempIssuerRating(m_sIssuerRating);
  static std::string sTempBondRating(m_sBondRating);

  sTempIssuerRating = m_sIssuerRating;
  sTempBondRating = m_sBondRating;
  if (sTempIssuerRating == "CCL") {
    sTempIssuerRating = "--";
  }

  if (sTempBondRating == "CCL") {
    sTempBondRating = "--";
  }

  if (sTempIssuerRating.length() > 0) {
    if (sTempIssuerRating == sTempBondRating) {
      return sTempIssuerRating.c_str();
    } else {
      if (sTempBondRating.length() > 0) {
        sTempIssuerRating += "/" + sTempBondRating;
        return sTempIssuerRating.c_str();
        // return sTempIssuerRating+"/"+sTempBondRating;
      } else {
        sTempIssuerRating += "/--";
        return sTempIssuerRating.c_str();
        // return sTempIssuerRating+"/--";
      }
    }
  } else {
    if (sTempBondRating.length() > 0) {
      sTempBondRating = std::string("--/") + sTempBondRating;
      return sTempBondRating.c_str();
      // return string("--/")+sTempBondRating;
    }
  }

  return "--";
}

const char* CBondInfoImpl::GetIssuerRatingEx() const {
  USE_FIELD(CBondInfoImpl, m_sInstitutionRating, false);
  const char* pRating = m_sInstitutionRating;
  if (strcmp(pRating, "AAA+") == 0) {
    return pRating;
  }

  return m_sIssuerRating;
}

bool CBondInfoImpl::CheckBondSubType(const std::string& sType) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (sType.find(m_sBondSubType) != std::string::npos) {
    return true;
  } else {
    return false;
  }
}

bool CBondInfoImpl::IsListedCompany() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  const IssuerInfo* pI =
      CQBIssuerInfo::instance().GetIssuerInfo((const char*)m_sIssuerCode);
  if (pI == NULL) return false;
  if (IsEmpty(pI->field((int)kIssuerInfo::Listed_Type))) return false;

  if (NULL != strstr(pI->field((int)kIssuerInfo::Listed_Type),
                     QString("A股").toLocal8Bit()))
    return true;
  if (NULL != strstr(pI->field((int)kIssuerInfo::Listed_Type),
                     QString("B股").toLocal8Bit()))
    return true;
  if (NULL != strstr(pI->field((int)kIssuerInfo::Listed_Type),
                     QString("H股").toLocal8Bit()))
    return true;
  return false;
}

bool CBondInfoImpl::IsCBRC_Financing_Platform() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);

  const IssuerInfo* pI =
      CQBIssuerInfo::instance().GetIssuerInfo((const char*)m_sIssuerCode);
  if (pI != NULL) {
    if (strcmp(pI->field((int)kIssuerInfo::CBRC_Financing_Platform), "Y") ==
        0) {
      return true;
    }
  }

  return false;
}

bool CBondInfoImpl::IsCDCAuthValid() const {
  if (!SSUserAccountManager::instance().HasAnyCDCAuthority()) return false;
  if (m_nCdcAuth <= 0) return true;
  auto& auth = SSUserAccountManager::instance().GetCDCAutority();
  return auth.find(m_nCdcAuth) != auth.end();

  return true;
}

bool CBondInfoImpl::CheckCommonUseType(const BLHCONDITION& Cond) const {
  // 待优化:避免多次以m_sIssuerCode来调用IsCommonUseType
  for (int i = 0; i < _countof(Cond.nCommonUse); i++) {
    if (Cond.nCommonUse[i] == CBondContainer::CommNone) return false;
    if (CheckCommonUseType(Cond.nCommonUse[i])) return true;
  }
  return false;
}

bool CBondInfoImpl::CheckCommonUseType(uint32_t nSubType) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  static const char strSW_Elect[] = "031301";
  static const char strSW_Steel[] = "0304";
  static const char strSW_Coal[] = "0302";
  static const char strSW_Cement[] = "032101";
  static const char strSW_Realty[] = "0315";
  static const char strSW_Traffic[] = "0314";
  switch (nSubType) {
    case CBondContainer::CommNone:
      return false;
      break;
    case CBondContainer::CommAll:
      return true;
      break;
    case CBondContainer::CommElect:  // 电力
      return IsCommonUseType(strSW_Elect, 2);
      break;
    case CBondContainer::CommSteel:  // 钢铁
      return IsCommonUseType(strSW_Steel, 1);
      break;
    case CBondContainer::CommCoal:  // 煤炭
      return IsCommonUseType(strSW_Coal, 1);
      break;
    case CBondContainer::CommCement:  // 水泥
      return IsCommonUseType(strSW_Cement, 2);
      break;
    case CBondContainer::CommRealty:  // 房地产
      return IsCommonUseType(strSW_Realty, 1);
      break;
    case CBondContainer::CommTraffic:  // 交运
      return IsCommonUseType(strSW_Traffic, 1);
      break;
    case CBondContainer::CommMunicipal:  // 城投
      return IsMunicipal();
      break;
    case CBondContainer::CommRailWay:  // 铁道
      return strcmp(m_sBondSubType, "RAB") == 0;
      break;
    case CBondContainer::CommListedCompany:  // 上市
      return IsListedCompany();
      break;
    case CBondContainer::CommGreenBond:  // 绿色债
      return IsGreenBond();
      break;
    case CBondContainer::CommCarbonNeutrality:  // 碳中和
      return IsCarbonNeutrality();
      break;
    default:
      return false;
      break;
  }

  return false;
}

bool CBondInfoImpl::IsGreenBond(void) const {
  const char* tag = GetBondTag();
  return (tag != nullptr && strstr(tag, "013") != nullptr);
}

bool CBondInfoImpl::IsCarbonNeutrality(void) const {
  const char* tag = GetBondTag();
  return (tag != nullptr && strstr(tag, "004") != nullptr);
}

bool CBondInfoImpl::IsBondRailway(void) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "RAB") == 0) return true;
  return false;
}

bool CBondInfoImpl::IsBondInsurance(void) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (IsCommonUseType("031902")) {
    if (strcmp(m_sBondSubType, "NCB") == 0) return true;
    if (strcmp(m_sBondSubType, "TET") == 0) return true;
  }
  return false;
}

bool CBondInfoImpl::IsBondBroker(void) const {
  return IsBondBroker_Corp() || IsBondBroker_Short() || IsBondBroker_Second();
}

bool CBondInfoImpl::IsBondBroker_Corp(void) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "SEB") == 0) return true;
  return false;
}

bool CBondInfoImpl::IsBondBroker_Short(void) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "SSB") == 0) return true;
  return false;
}

bool CBondInfoImpl::IsBondBroker_Second(void) const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  if (strcmp(m_sBondSubType, "SES") == 0) return true;
  return false;
}

bool CBondInfoImpl::IsBondBank(void) const {
  return IsBondBankSecond() || IsBondBankPerpetual() || IsBondCommercialBank();
}

bool CBondInfoImpl::IsBondFinancialOther(void) const {
  //	static std::vector<string> tgtType = {
  //"PSB","CBB","CSB","CXB","NCB","SFB","SEB","SSB","SES","HJB","TET","TLC"
  //};所有金融机构债
  static std::vector<std::string> vctFinanOther = {
      "PSB",  // 政策性银行次级债
      "CSB",  // 商业银行次级债
      "CXB",  // 商业银行混合资本债券
      "SFB",  // 特种金融债
      "HJB"   // 汇金债
  };  // 以上直接判定为其他金融机构债

  static std::vector<std::string> vctFinan = {
      "CBB", "NCB", "TET"};  // 排除了证券债("SEB","SSB","SES")后的金融机构债

  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  const char* subType = m_sBondSubType;
  if (std::find(vctFinanOther.begin(), vctFinanOther.end(), subType) !=
      vctFinanOther.end())
    return true;  // 其他金融机构债
  if (std::find(vctFinan.begin(), vctFinan.end(), subType) == vctFinan.end())
    return false;  // 非金融机构债

  if (IsBondBank() || IsBondInsurance()) return false;  // 排除商金债和保险债
  return true;
}

bool CBondInfoImpl::IsCommonUseType(const char* sType, int swLevel) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerCode, false);
  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI = IMap.GetIssuerInfo((const char*)m_sIssuerCode);
  if (!pI) return false;

  if (swLevel == 2)  // 二级行业匹配
  {
    return strcmp(sType, pI->field((int)kIssuerInfo::SW_2021_Subsector_Code)) ==
           0;
  } else if (swLevel == 1)  // 一级行业匹配
  {
    return strcmp(sType, pI->field((int)kIssuerInfo::SW_2021_Sector_Code)) == 0;
  }
  return false;
}

void CBondInfoImpl::SetIssueRate(const char* sIssueRate) {
  USE_FIELD(CBondInfoImpl, m_IssueRate, true);
  m_IssueRate = sIssueRate;
}

void CBondInfoImpl::SetPlannedExerciseDate(const char* sDate) {
  USE_FIELD(CBondInfoImpl, m_PlannedExerciseDate, true);
  m_PlannedExerciseDate = sDate;
}

void CBondInfoImpl::SetNextCoupon_Date(const char* sDate) {
  USE_FIELD(CBondInfoImpl, m_NextCoupon_Date, true);
  m_NextCoupon_Date = sDate;
}

void CBondInfoImpl::SetConversionRate(const char* sRate) {
  USE_FIELD(CBondInfoImpl, m_ConversionRate, true);
  m_ConversionRate = sRate;
}

const char* CBondInfoImpl::GetBondKey() const {
  USE_FIELD(CBondInfoImpl, m_sBondKey, false);
  return m_sBondKey;
}

const char* CBondInfoImpl::GetBondCode() const {
  USE_FIELD(CBondInfoImpl, m_sBondID, false);
  return m_sBondID;
}

const char* CBondInfoImpl::GetListedMarket() const {
  USE_FIELD(CBondInfoImpl, m_sListedMarket, false);
  return m_sListedMarket;
}

const char* CBondInfoImpl::GetCombBondKey() const {
  USE_FIELD(CBondInfoImpl, m_sCombBondKey, false);
  return m_sCombBondKey;
}

const char* CBondInfoImpl::GetCombBondCode() const {
  USE_FIELD(CBondInfoImpl, m_sCombBondID, false);
  return m_sCombBondID;
}

const char* CBondInfoImpl::GetCBRRating() const {
  USE_FIELD(CBondInfoImpl, m_sCBRRating, false);
  return m_sCBRRating;
}

const char* CBondInfoImpl::GetChinaDCState() const {
  USE_FIELD(CBondInfoImpl, m_sChinaDCState, false);
  return m_sChinaDCState;
}

const char* CBondInfoImpl::GetCDCRating() const {
  USE_FIELD(CBondInfoImpl, m_sCDCRating, false);
  return m_sCDCRating;
}

const char* CBondInfoImpl::GetCSIRating() const {
  USE_FIELD(CBondInfoImpl, m_sCSIRating, false);
  return m_sCSIRating;
}

const char* CBondInfoImpl::GetCurrency() const {
  USE_FIELD(CBondInfoImpl, m_sCurrency, false);
  return m_sCurrency;
}

std::string CBondInfoImpl::GetBondJianpin() const {
  // USE_FIELD(CBondInfoImpl,m_sJianpin, false);
  /*
          [内存优化][scofined.qi]
          GetPinyin最后一个字段是用来指示简拼,全拼,还是都计算
  */
  if (!IsEmpty(m_sShortName)) {
    std::string jian, quan;
    qb::PinyinManager::instance().GetPinyin(m_sShortName, jian, quan,
                                            qb::IPinyin::kFlagJian);
    return jian;
  }
  return "";
}

std::string CBondInfoImpl::GetBondQuanpin() const {
  // USE_FIELD(CBondInfoImpl,m_sQuanpin, false);
  /*
  [内存优化][scofined.qi]
  GetPinyin最后一个字段是用来指示简拼,全拼,还是都计算
  */
  if (!IsEmpty(m_sShortName)) {
    std::string jian, quan;
    qb::PinyinManager::instance().GetPinyin(m_sShortName, jian, quan,
                                            qb::IPinyin::kFlagFull);
    return quan;
  }
  return "";
}

const char* CBondInfoImpl::GetMarketType() const {
  USE_FIELD(CBondInfoImpl, m_sMarketType, false);
  return m_sMarketType;
}

const char* CBondInfoImpl::GetBondSubType() const {
  USE_FIELD(CBondInfoImpl, m_sBondSubType, false);
  return m_sBondSubType;
}

const char* CBondInfoImpl::GetIssuerRating() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerRating, false);
  return m_sIssuerRating;
}

const char* CBondInfoImpl::GetIssuerRatingInstitutionCode() const {
  USE_FIELD(CBondInfoImpl, m_sIssuerRatingInstitutionCode, false);
  return m_sIssuerRatingInstitutionCode;
}

const char* CBondInfoImpl::GetInstitutionRating() const {
  USE_FIELD(CBondInfoImpl, m_sInstitutionRating, false);
  return m_sInstitutionRating;
}

const char* CBondInfoImpl::GetBondRating() const {
  USE_FIELD(CBondInfoImpl, m_sBondRating, false);
  return m_sBondRating;
}

const char* CBondInfoImpl::GetListDate() const {
  USE_FIELD(CBondInfoImpl, m_sListDate, false);
  return m_sListDate;
}

const char* CBondInfoImpl::GetInterestStartDate() const {
  USE_FIELD(CBondInfoImpl, m_sInterestStartDate, false);
  return m_sInterestStartDate;
}

const char* CBondInfoImpl::GetMaturityDate() const {
  USE_FIELD(CBondInfoImpl, m_sMaturityDate, false);
  return m_sMaturityDate;
}

const char* CBondInfoImpl::GetPaymentDate() const {
  USE_FIELD(CBondInfoImpl, m_sPaymentDate, false);
  return m_sPaymentDate;
}

int CBondInfoImpl::GetPayDate() const {
  USE_FIELD(CBondInfoImpl, m_nPayDate, false);
  return m_nPayDate;
}

const char* CBondInfoImpl::GetOptionDate() const {
  USE_FIELD(CBondInfoImpl, m_sOptionDate, false);
  return m_sOptionDate;
}

const char* CBondInfoImpl::GetRateType() const {
  USE_FIELD(CBondInfoImpl, m_sRateType, false);
  return m_sRateType;
}

const char* CBondInfoImpl::GetCouponType() const {
  USE_FIELD(CBondInfoImpl, m_sCouponType, false);
  return m_sCouponType;
}

const char* CBondInfoImpl::GetCouponFrequency() const {
  USE_FIELD(CBondInfoImpl, m_sCouponFrequency, false);
  return m_sCouponFrequency;
}

const char* CBondInfoImpl::GetCompoundFrequency() const {
  USE_FIELD(CBondInfoImpl, m_sCompoundFrequency, false);
  return m_sCompoundFrequency;
}

const char* CBondInfoImpl::GetInterestBasis() const {
  USE_FIELD(CBondInfoImpl, m_sInterestBasis, false);
  return m_sInterestBasis;
}

const char* CBondInfoImpl::GetOptionType() const {
  USE_FIELD(CBondInfoImpl, m_sOptionType, false);
  return m_sOptionType;
}

const char* CBondInfoImpl::GetMaturityTerm() const {
  USE_FIELD(CBondInfoImpl, m_sMaturityTerm, false);
  return m_sMaturityTerm;
}

bool CBondInfoImpl::IsBondPrivate() const {
  if (IsBondNonPublicCor() || IsBondPPN()) {
    return true;
  }

  return false;
}

const char* CBondInfoImpl::GetRatingInstitutionShortName(bool eng) const {
  USE_FIELD(CBondInfoImpl, m_sIssuerRatingInstitutionCode, false);

  CQBIssuerInfo& IMap = CQBIssuerInfo::instance();
  const IssuerInfo* pI =
      IMap.GetIssuerInfo((const char*)m_sIssuerRatingInstitutionCode);
  if (pI != NULL) {
    if (eng) return pI->field((int)kIssuerInfo::Short_Name_E);
    return pI->field((int)kIssuerInfo::Short_Name_C);
  }

  return "";
}
void CBondInfoImpl::SetIssueType(const char* szIssueType) {  // m_sIssueType
  USE_FIELD(CBondInfoImpl, m_sIssueType, true);
  m_sIssueType = szIssueType;
}

int CBondInfoImpl::GetIssueType() {
  // 2016/12/20 by devin.zhang: edmund确认，无招标方式时，用RAT
  USE_FIELD(CBondInfoImpl, m_sIssueType, false);
  const char* pIssueType = m_sIssueType;
  if (strcmp(pIssueType, "RAT") == 0)
    return IssueRAT;  // 利率
  else if (strcmp(pIssueType, "PRC") == 0)
    return IssuePRC;  // 价格
  else if (strcmp(pIssueType, "SPD") == 0)
    return IssueSPD;  // 利差
  else if (strcmp(pIssueType, "AMT") == 0)
    return IssueAMT;  // 数量招标

  return IssueRAT;
  // return IssueNONE;
}

// PRIM - 3130  利差的判断条件：Auction表Auction_Type=SPD 或
// bond表Coupon_Type=FRN  申购页面
int CBondInfoImpl::GetIssueTypePurchase() {
  USE_FIELD(CBondInfoImpl, m_sIssueType, false);
  const char* pIssueType = m_sIssueType;
  if (strcmp(pIssueType, "RAT") == 0)
    return IssueRAT;  // 利率
  else if (strcmp(pIssueType, "PRC") == 0)
    return IssuePRC;  // 价格
  else if (strcmp(pIssueType, "SPD") == 0 || strcmp(m_sCouponType, "FRN") == 0)
    return IssueSPD;  // 利差
  else if (strcmp(pIssueType, "AMT") == 0)
    return IssueAMT;  // 数量招标

  return IssueRAT;
}

const char* CBondInfoImpl::GetIssueStartDate() const {
  USE_FIELD(CBondInfoImpl, m_sIssueStartDate, false);
  return m_sIssueStartDate;
}

const char* CBondInfoImpl::GetIssueEndDate() const {
  USE_FIELD(CBondInfoImpl, m_sIssueEndDate, false);
  return m_sIssueEndDate;
}

const char* CBondInfoImpl::GetIssueEndTime() const {
  USE_FIELD(CBondInfoImpl, m_sIssueEndTime, false);
  return m_sIssueEndTime;
}

const char* CBondInfoImpl::GetIssuePeriod() const {
  USE_FIELD(CBondInfoImpl, m_sIssuePeriod, false);
  return m_sIssuePeriod;
}

int CBondInfoImpl::GetAuctionTimeStart() const {
  USE_FIELD(CBondInfoImpl, m_nAuctionTimeStart, false);
  return m_nAuctionTimeStart;
}

int CBondInfoImpl::GetAuctionTimeEnd() const {
  USE_FIELD(CBondInfoImpl, m_nAuctionTimeEnd, false);
  return m_nAuctionTimeEnd;
}

int CBondInfoImpl::GetIsQuotTopflag() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetStickFlag() ? 1 : 0;
}

char CBondInfoImpl::GetMortgage() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetMortgageFlag();
}

char CBondInfoImpl::GetCrossmarket() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetCrossmarketFlag();
}

char CBondInfoImpl::GetIsMunicipal() const {
  USE_FIELD(CBondInfoImpl, m_flag, false);
  return m_flag.GetMunicipalFlag();
}

const char* CBondInfoImpl::GetWarrant() const {
  USE_FIELD(CBondInfoImpl, m_sWarrant, false);
  return m_sWarrant;
}

const char* CBondInfoImpl::GetMainUnderwriters() const {
  USE_FIELD(CBondInfoImpl, m_sMainUnderwriters, false);
  return m_sMainUnderwriters;
}

const char* CBondInfoImpl::GetJointUnderwriters() const {
  USE_FIELD(CBondInfoImpl, m_sJointUnderwriters, false);
  return m_sJointUnderwriters;
}

const char* CBondInfoImpl::GetUnderwrites() const {
  USE_FIELD(CBondInfoImpl, m_sUnderwrites, false);
  return m_sUnderwrites;
}

const char* CBondInfoImpl::GetBidLimitBottom() const {
  USE_FIELD(CBondInfoImpl, m_sBidLimitBottom, false);
  return m_sBidLimitBottom;
}

const char* CBondInfoImpl::GetBidLimitTop() const {
  USE_FIELD(CBondInfoImpl, m_sBidLimitTop, false);
  return m_sBidLimitTop;
}

const char* CBondInfoImpl::GetAuctionFlr() const {
  USE_FIELD(CBondInfoImpl, m_sAuction_Flr, false);
  return m_sAuction_Flr;
}

const char* CBondInfoImpl::GetAuctionCap() const {
  USE_FIELD(CBondInfoImpl, m_sAuction_Cap, false);
  return m_sAuction_Cap;
}

const char* CBondInfoImpl::GetAuctionStep() const {
  USE_FIELD(CBondInfoImpl, m_sAuction_Step, false);
  return m_sAuction_Step;
}

const char* CBondInfoImpl::GetAuctionUnit() const {
  USE_FIELD(CBondInfoImpl, m_sAuction_Unit, false);
  return m_sAuction_Unit;
}

const char* CBondInfoImpl::GetRemainDate() const {
  USE_FIELD(CBondInfoImpl, m_sRemainDate, false);
  return m_sRemainDate;
}

const char* CBondInfoImpl::GetSceniority() const {
  USE_FIELD(CBondInfoImpl, m_Sceniority, false);
  return m_Sceniority;
}

const char* CBondInfoImpl::GetCategoryFlag() const {
  USE_FIELD(CBondInfoImpl, m_CategoryFlag, false);
  return m_CategoryFlag;
}

std::string CBondInfoImpl::GetBondName() const {
  USE_FIELD(CBondInfoImpl, m_sFullName, false);
  const char* str = m_sFullName;
  return str;
}
